libextractor

GNU libextractor
Log | Files | Refs | Submodules | README | LICENSE

commit 1b630d583ee5080bf2bb471fbe86abf08c8644b9
parent bfcc71669914b67538855d7ae8704391825c63d3
Author: Christian Grothoff <christian@grothoff.org>
Date:   Fri,  3 Aug 2012 12:40:06 +0000

rewriting ogg

Diffstat:
Msrc/plugins/Makefile.am | 6+++---
Msrc/plugins/fuzz_default.sh | 6+++---
Dsrc/plugins/fuzz_thumbnail.sh | 39---------------------------------------
Msrc/plugins/ogg_extractor.c | 178+++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------
4 files changed, 135 insertions(+), 94 deletions(-)

diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am @@ -15,12 +15,12 @@ if HAVE_VORBISFILE PLUGIN_OGG=libextractor_ogg.la endif -#plugin_LTLIBRARIES = \ +plugin_LTLIBRARIES = \ + $(PLUGIN_OGG) # libextractor_id3.la \ # libextractor_id3v2.la \ # libextractor_ebml.la \ # libextractor_s3m.la \ -# $(PLUGIN_OGG) \ # libextractor_png.la \ # libextractor_mp3.la @@ -84,7 +84,7 @@ libextractor_png_la_LIBADD = \ EXTRA_DIST = template_extractor.c if HAVE_ZZUF - fuzz_tests=fuzz_default.sh fuzz_thumbnail.sh + fuzz_tests=fuzz_default.sh endif TESTS = $(fuzz_tests) \ No newline at end of file diff --git a/src/plugins/fuzz_default.sh b/src/plugins/fuzz_default.sh @@ -24,11 +24,11 @@ do trap "echo $tmpfile caused SIGSEGV ; exit 1" SEGV while [ $seed -lt $ZZSTOPSEED ] do -# echo "file $file seed $seed" + echo "file $file seed $seed" zzuf -c -s $seed cat "$file" > "$tmpfile" - if ! "$bindir/extract" "$tmpfile" > /dev/null + if ! "$bindir/extract" -i "$tmpfile" > /dev/null then - echo "$tmpfile caused error exit" + echo "$tmpfile with seed $seed failed" exit 1 fi seed=`expr $seed + 1` diff --git a/src/plugins/fuzz_thumbnail.sh b/src/plugins/fuzz_thumbnail.sh @@ -1,39 +0,0 @@ -#!/bin/sh - -ZZSTARTSEED=0 -ZZSTOPSEED=100 - -# fallbacks for direct, non-"make check" usage -if test x"$testdatadir" = x"" -then - testdatadir=../../test -fi -if test x"$bindir" = x"" -then - bindir=`grep "^prefix = " ./Makefile | cut -d ' ' -f 3` - bindir="$bindir/bin" -fi - - -for file in $testdatadir/*.bmp $testdatadir/*.gif $testdatadir/*.png $testdatadir/*.ppm -do - if test -f "$file" - then - tmpfile=`mktemp extractortmp.XXXXXX` || exit 1 - seed=$ZZSTARTSEED - trap "echo $tmpfile caused SIGSEGV ; exit 1" SEGV - while [ $seed -lt $ZZSTOPSEED ] - do -# echo "file $file seed $seed" - zzuf -c -s $seed cat "$file" > "$tmpfile" - if ! "$bindir/extract" -n -l thumbnailffmpeg:thumbnailqt:thumbnailgtk "$tmpfile" > /dev/null - then - echo "$tmpfile caused error exit" - exit 1 - fi - seed=`expr $seed + 1` - done - rm -f "$tmpfile" - fi -done - diff --git a/src/plugins/ogg_extractor.c b/src/plugins/ogg_extractor.c @@ -1,10 +1,10 @@ /* This file is part of libextractor. - (C) 2002, 2003, 2009 Vidyut Samanta and Christian Grothoff + (C) 2002, 2003, 2009, 2012 Vidyut Samanta and Christian Grothoff libextractor is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 2, or (at your + by the Free Software Foundation; either version 3, or (at your option) any later version. libextractor is distributed in the hope that it will be useful, but @@ -17,84 +17,162 @@ Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - #include "platform.h" #include "extractor.h" #include "extractor_plugins.h" +#include <vorbis/vorbisfile.h> -#define DEBUG_EXTRACT_OGG 0 +/** + * Bytes each ogg file must begin with (not used, but we might + * choose to add this back in the future to improve performance + * for non-ogg files). + */ #define OGG_HEADER 0x4f676753 -#if HAVE_VORBIS_VORBISFILE_H -#include <vorbis/vorbisfile.h> -#else -#error You must install the libvorbis header files! -#endif - -static char * -get_comment (vorbis_comment * vc, char *label) -{ - char *tag; - if (vc && (tag = vorbis_comment_query (vc, label, 0)) != NULL) - return tag; - return NULL; -} +/** + * Custom read function for ogg. + * + * @param ptr where to write the data + * @param size number of bytes to read per member + * @param nmemb number of members to read + * @param datasource the 'struct EXTRACTOR_ExtractContext' + * @return 0 on end-of-data, 0 with errno set to indicate read error + */ static size_t -readOgg (void *ptr, size_t size, size_t nmemb, void *datasource) +read_ogg (void *ptr, size_t size, size_t nmemb, void *datasource) { - struct EXTRACTOR_PluginList *plugin = datasource; - int64_t ret; - unsigned char *read_data; + struct EXTRACTOR_ExtractContext *ec = datasource; + void *data; + ssize_t ret; - ret = pl_read (plugin, &read_data, size*nmemb); - if (ret <= 0) - { - if (ret < 0) - errno = EIO; + data = NULL; + ret = ec->read (ec->cls, + &data, + size * nmemb); + if (-1 == ret) return 0; - } - memcpy (ptr, read_data, ret); + if (0 == ret) + { + errno = 0; + return 0; + } + memcpy (ptr, data, ret); + errno = 0; return ret; } -#define ADD(t,s) do { if (0 != (ret = proc (proc_cls, "ogg", t, EXTRACTOR_METAFORMAT_UTF8, "text/plain", s, strlen(s)+1))) goto FINISH; } while (0) -#define ADDG(t,d) do { m = get_comment (comments, d); if (m != NULL) ADD(t,m); } while (0) +/** + * Seek to a particular position in the file. + * + * @param datasource the 'struct EXTRACTOR_ExtractContext' + * @param offset where to seek + * @param whence how to seek + * @return -1 on error + */ +static int +seek_ogg (void *datasource, + ogg_int64_t offset, + int whence) +{ + struct EXTRACTOR_ExtractContext *ec = datasource; + + if (-1 == ec->seek (ec->cls, + (int64_t) offset, + whence)) + return -1; + return 0; +} + + +/** + * Tell ogg where we are in the file + * + * @param datasource the 'struct EXTRACTOR_ExtractContext' + * @return + */ +static long +tell_ogg (void *datasource) +{ + struct EXTRACTOR_ExtractContext *ec = datasource; + + return (long) ec->seek (ec->cls, + 0, + SEEK_CUR); +} + + + +/** + * Extract the associated meta data for a given label from vorbis. + * + * @param vc vorbis comment data + * @param label label marking the desired entry + * @return NULL on error, otherwise the meta data + */ +static char * +get_comment (vorbis_comment *vc, + const char *label) +{ + if (NULL == vc) + return NULL; + return vorbis_comment_query (vc, label, 0); +} + + +/** + * Extract meta data from vorbis using the given LE type and value. + * + * @param t LE meta data type + * @param s meta data to add + */ +#define ADD(t,s) do { if (0 != (ret = ec->proc (ec->cls, "ogg", t, EXTRACTOR_METAFORMAT_UTF8, "text/plain", s, strlen(s)+1))) goto FINISH; } while (0) + + +/** + * Extract meta data from vorbis using the given LE type and label. + * + * @param t LE meta data type + * @param d vorbis meta data label + */ +#define ADDG(t,d) do { m = get_comment (comments, d); if (NULL != m) ADD(t,m); } while (0) + -/* mimetype = application/ogg */ -int -EXTRACTOR_ogg_extract_method (struct EXTRACTOR_PluginList *plugin, - EXTRACTOR_MetaDataProcessor proc, void *proc_cls) +/** + * Main entry method for the 'application/ogg' extraction plugin. + * + * @param ec extraction context provided to the plugin + */ +void +EXTRACTOR_ogg_extract_method (struct EXTRACTOR_ExtractContext *ec) { + uint64_t fsize; + ov_callbacks callbacks; OggVorbis_File vf; vorbis_comment *comments; - ov_callbacks callbacks; int ret; - int64_t fsize; const char *m; - fsize = pl_get_fsize (plugin); - if (fsize > 0 && fsize < 2 * sizeof (int)) - return 1; - if (fsize == 0) - return 1; + fsize = ec->get_size (ec->cls); + if (fsize < 8) + return; /* TODO: rewrite pl_seek() to be STDIO-compatible (SEEK_END) and enable seeking. */ - callbacks.read_func = &readOgg; - callbacks.seek_func = NULL; + callbacks.read_func = &read_ogg; + callbacks.seek_func = &seek_ogg; callbacks.close_func = NULL; - callbacks.tell_func = NULL; - if (0 != ov_open_callbacks (plugin, &vf, NULL, 0, callbacks)) + callbacks.tell_func = &tell_ogg; + if (0 != ov_open_callbacks (ec, &vf, NULL, 0, callbacks)) { ov_clear (&vf); - return 1; + return; } comments = ov_comment (&vf, -1); if (NULL == comments) { ov_clear (&vf); - return 1; + return; } ret = 0; ADD (EXTRACTOR_METATYPE_MIMETYPE, "application/ogg"); @@ -119,5 +197,7 @@ EXTRACTOR_ogg_extract_method (struct EXTRACTOR_PluginList *plugin, ADDG (EXTRACTOR_METATYPE_SONG_VERSION, "version"); FINISH: ov_clear (&vf); - return 1; } + +/* end of ogg_extractor.c */ +