libextractor

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

s3m_extractor.c (3757B)


      1 /*
      2      This file is part of libextractor.
      3      Copyright (C) 2002, 2003, 2004, 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/s3m_extractor.c
     22  * @brief plugin to support Scream Tracker (S3M) files
     23  * @author Toni Ruottu
     24  * @author Christian Grothoff
     25  */
     26 #include "platform.h"
     27 #include "extractor.h"
     28 #include "le_architecture.h"
     29 
     30 
     31 LE_NETWORK_STRUCT_BEGIN
     32 struct S3MHeader
     33 {
     34   char song_name[28];
     35   uint8_t byte_1A;
     36   uint8_t file_type; /* 0x10 == ST3 module */
     37   uint8_t unknown1[2];
     38   uint16_t number_of_orders LE_PACKED; /* should be even */
     39   uint16_t number_of_instruments LE_PACKED;
     40   uint16_t number_of_patterns LE_PACKED;
     41   uint16_t flags LE_PACKED;
     42   uint16_t created_with_version LE_PACKED;
     43   uint16_t file_format_info LE_PACKED;
     44   char SCRM[4];
     45   uint8_t global_volume;
     46   uint8_t initial_speed;
     47   uint8_t initial_tempo;
     48   uint8_t master_volume;
     49   uint8_t ultra_click_removal;
     50   uint8_t default_channel_positions;
     51   uint8_t unknown2[8];
     52   uint16_t special LE_PACKED;
     53   uint8_t channel_settings[32];
     54 };
     55 LE_NETWORK_STRUCT_END
     56 
     57 
     58 /**
     59  * Give meta data to LE 'proc' callback using the given LE type and value.
     60  *
     61  * @param t LE meta data type
     62  * @param s meta data to add
     63  */
     64 #define ADD(s, t) do { if (0 != ec->proc (ec->cls, "s3m", t, \
     65                                           EXTRACTOR_METAFORMAT_UTF8, \
     66                                           "text/plain", s, strlen (s) \
     67                                           + 1)) return; \
     68 } while (0)
     69 
     70 
     71 /**
     72  * Extractor based upon Scream Tracker 3.20 spec at http://16-bits.org/s3m/
     73  *
     74  * Looks like the format was defined by the software implementation,
     75  * and that implementation was for little-endian platform, which means
     76  * that the format is little-endian.
     77  *
     78  * @param ec extraction context
     79  */
     80 void
     81 EXTRACTOR_s3m_extract_method (struct EXTRACTOR_ExtractContext *ec)
     82 {
     83   void *data;
     84   struct S3MHeader header;
     85   char song_name_NT[29];
     86 
     87   if ((ssize_t) sizeof (header) >
     88       ec->read (ec->cls,
     89                 &data,
     90                 sizeof (header)))
     91     return;
     92   memcpy (&header, data, sizeof (header));
     93   if ( (0x1A != header.byte_1A) ||
     94        (0 != memcmp (header.SCRM, "SCRM", 4)) )
     95     return;
     96   header.number_of_orders = LE_le16toh (header.number_of_orders);
     97   header.number_of_instruments = LE_le16toh (header.number_of_instruments);
     98   header.number_of_patterns = LE_le16toh (header.number_of_patterns);
     99   header.flags = LE_le16toh (header.flags);
    100   header.created_with_version = LE_le16toh (header.created_with_version);
    101   header.file_format_info = LE_le16toh (header.file_format_info);
    102   header.special = LE_le16toh (header.special);
    103   memcpy (song_name_NT, header.song_name, 28);
    104   song_name_NT[28] = '\0';
    105   ADD ("audio/x-s3m", EXTRACTOR_METATYPE_MIMETYPE);
    106   ADD (song_name_NT, EXTRACTOR_METATYPE_TITLE);
    107   /* TODO: turn other header data into useful metadata (i.e. RESOURCE_TYPE).
    108    * Also, disabled instruments can be (and are) used to carry user-defined text.
    109    */
    110 }
    111 
    112 
    113 /* end of s3m_extractor.c */