"Fossies" - the Fresh Open Source Software Archive

Member "libextractor-1.11/src/plugins/ogg_extractor.c" (30 Jan 2021, 5677 Bytes) of package /linux/privat/libextractor-1.11.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "ogg_extractor.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 1.5_vs_1.6.

    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
  154 EXTRACTOR_ogg_extract_method (struct EXTRACTOR_ExtractContext *ec)
  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");
  192   ADDG (EXTRACTOR_METATYPE_CONTACT_INFORMATION, "contact");
  193   ADDG (EXTRACTOR_METATYPE_GENRE, "genre");
  194   ADDG (EXTRACTOR_METATYPE_CREATION_DATE, "date");
  195   ADDG (EXTRACTOR_METATYPE_COMMENT, "");
  196   ADDG (EXTRACTOR_METATYPE_LOCATION_SUBLOCATION, "location");
  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");
  202   ADDG (EXTRACTOR_METATYPE_SONG_VERSION, "version");
  203 FINISH:
  204   ov_clear (&vf);
  205 }
  206 
  207 
  208 /* end of ogg_extractor.c */