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
EXTRACTOR_s3m_extract_method(struct EXTRACTOR_ExtractContext * ec)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 */
114