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 */