diff options
author | Christian Grothoff <christian@grothoff.org> | 2009-12-19 12:32:34 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2009-12-19 12:32:34 +0000 |
commit | c21fafc7b640836719597b425a7e598524137575 (patch) | |
tree | 0a397cf1b7ca5181dd14bf07f61ef9385051a5b3 /src/plugins/sid_extractor.c | |
parent | fe641c0d363f2bcb75cef8d7b67e44f4d972ba47 (diff) | |
download | libextractor-c21fafc7b640836719597b425a7e598524137575.tar.gz libextractor-c21fafc7b640836719597b425a7e598524137575.zip |
sid
Diffstat (limited to 'src/plugins/sid_extractor.c')
-rw-r--r-- | src/plugins/sid_extractor.c | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/src/plugins/sid_extractor.c b/src/plugins/sid_extractor.c new file mode 100644 index 0000000..2465982 --- /dev/null +++ b/src/plugins/sid_extractor.c | |||
@@ -0,0 +1,191 @@ | |||
1 | /* | ||
2 | * This file is part of libextractor. | ||
3 | * (C) 2006, 2007 Toni Ruottu | ||
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 2, 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., 59 Temple Place - Suite 330, | ||
18 | * Boston, MA 02111-1307, USA. | ||
19 | * | ||
20 | */ | ||
21 | #include "platform.h" | ||
22 | #include "extractor.h" | ||
23 | |||
24 | |||
25 | #define SID1_HEADER_SIZE 0x76 | ||
26 | #define SID2_HEADER_SIZE 0x7c | ||
27 | |||
28 | /* flags */ | ||
29 | |||
30 | #define MUSPLAYER_FLAG 0x01 | ||
31 | #define PLAYSID_FLAG 0x02 | ||
32 | #define PAL_FLAG 0x04 | ||
33 | #define NTSC_FLAG 0x08 | ||
34 | #define MOS6581_FLAG 0x10 | ||
35 | #define MOS8580_FLAG 0x20 | ||
36 | |||
37 | typedef char sidwrd[2]; | ||
38 | typedef char sidlongwrd[4]; | ||
39 | |||
40 | struct header | ||
41 | { | ||
42 | char magicid[4]; | ||
43 | sidwrd sidversion; | ||
44 | sidwrd dataoffset; | ||
45 | sidwrd loadaddr; | ||
46 | sidwrd initaddr; | ||
47 | sidwrd playaddr; | ||
48 | sidwrd songs; | ||
49 | sidwrd firstsong; | ||
50 | sidlongwrd speed; | ||
51 | char title[32]; | ||
52 | char artist[32]; | ||
53 | char copyright[32]; | ||
54 | sidwrd flags; /* version 2 specific fields start */ | ||
55 | char startpage; | ||
56 | char pagelength; | ||
57 | sidwrd reserved; | ||
58 | }; | ||
59 | |||
60 | static int | ||
61 | sidword (const sidwrd data) | ||
62 | { | ||
63 | int value = (unsigned char) data[0] * 0x100 + (unsigned char) data[1]; | ||
64 | return value; | ||
65 | |||
66 | } | ||
67 | |||
68 | #define ADD(s,t) do { if (0 != proc (proc_cls, "sid", t, EXTRACTOR_METAFORMAT_UTF8, "text/plain", s, strlen(s)+1)) return 1; } while (0) | ||
69 | |||
70 | /* "extract" keyword from a SID file | ||
71 | * | ||
72 | * This plugin is based on the nsf extractor | ||
73 | * | ||
74 | */ | ||
75 | |||
76 | int | ||
77 | EXTRACTOR_sid_extract (const char *data, | ||
78 | size_t size, | ||
79 | EXTRACTOR_MetaDataProcessor proc, | ||
80 | void *proc_cls, | ||
81 | const char *options) | ||
82 | { | ||
83 | unsigned int flags; | ||
84 | int version; | ||
85 | char album[33]; | ||
86 | char artist[33]; | ||
87 | char copyright[33]; | ||
88 | char songs[32]; | ||
89 | char startingsong[32]; | ||
90 | char sidversion[32]; | ||
91 | const struct header *head; | ||
92 | |||
93 | /* Check header size */ | ||
94 | |||
95 | if (size < SID1_HEADER_SIZE) | ||
96 | return 0; | ||
97 | head = (const struct header *) data; | ||
98 | |||
99 | /* Check "magic" id bytes */ | ||
100 | if (memcmp (head->magicid, "PSID", 4) && | ||
101 | memcmp (head->magicid, "RSID", 4)) | ||
102 | return 0; | ||
103 | |||
104 | /* Mime-type */ | ||
105 | ADD ("audio/prs.sid", EXTRACTOR_METATYPE_MIMETYPE); | ||
106 | |||
107 | /* Version of SID format */ | ||
108 | version = sidword (head->sidversion); | ||
109 | snprintf (sidversion, | ||
110 | sizeof(sidversion), | ||
111 | "%d", | ||
112 | version); | ||
113 | ADD (sidversion, EXTRACTOR_METATYPE_FORMAT_VERSION); | ||
114 | |||
115 | /* Get song count */ | ||
116 | snprintf (songs, | ||
117 | sizeof(songs), | ||
118 | "%d", sidword (head->songs)); | ||
119 | ADD (songs, EXTRACTOR_METATYPE_SONG_COUNT); | ||
120 | |||
121 | /* Get number of the first song to be played */ | ||
122 | snprintf (startingsong, | ||
123 | sizeof(startingsong), | ||
124 | "%d", | ||
125 | sidword (head->firstsong)); | ||
126 | ADD (startingsong, EXTRACTOR_METATYPE_STARTING_SONG); | ||
127 | |||
128 | |||
129 | /* name, artist, copyright fields */ | ||
130 | memcpy (&album, head->title, 32); | ||
131 | album[32] = '\0'; | ||
132 | ADD (album, EXTRACTOR_METATYPE_ALBUM); | ||
133 | |||
134 | memcpy (&artist, head->artist, 32); | ||
135 | artist[32] = '\0'; | ||
136 | ADD (artist, EXTRACTOR_METATYPE_ARTIST); | ||
137 | |||
138 | memcpy (©right, head->copyright, 32); | ||
139 | copyright[32] = '\0'; | ||
140 | ADD (copyright, EXTRACTOR_METATYPE_COPYRIGHT); | ||
141 | |||
142 | |||
143 | if ( (version < 2) || (size < SID2_HEADER_SIZE)) | ||
144 | return 0; | ||
145 | |||
146 | /* Version 2 specific options follow | ||
147 | * | ||
148 | * Note: Had some troubles understanding specification | ||
149 | * on the flags in version 2. I hope this is correct. | ||
150 | */ | ||
151 | flags = sidword (head->flags); | ||
152 | /* MUS data */ | ||
153 | if (flags & MUSPLAYER_FLAG) | ||
154 | ADD ("Compute!'s Sidplayer", EXTRACTOR_METATYPE_CREATED_BY_SOFTWARE); | ||
155 | |||
156 | /* PlaySID data */ | ||
157 | if (flags & PLAYSID_FLAG) | ||
158 | ADD ("PlaySID", EXTRACTOR_METATYPE_CREATED_BY_SOFTWARE); | ||
159 | |||
160 | |||
161 | /* PAL or NTSC */ | ||
162 | |||
163 | if (flags & PAL_FLAG) | ||
164 | { | ||
165 | if (flags & NTSC_FLAG) | ||
166 | ADD ("PAL/NTSC", EXTRACTOR_METATYPE_BROADCAST_TELEVISION_SYSTEM); | ||
167 | else | ||
168 | ADD ("PAL", EXTRACTOR_METATYPE_BROADCAST_TELEVISION_SYSTEM); | ||
169 | } | ||
170 | else | ||
171 | { | ||
172 | if (flags & NTSC_FLAG) | ||
173 | ADD ("NTSC", EXTRACTOR_METATYPE_BROADCAST_TELEVISION_SYSTEM); | ||
174 | } | ||
175 | |||
176 | /* Detect SID Chips suitable for play the files */ | ||
177 | if (flags & MOS6581_FLAG) | ||
178 | { | ||
179 | if (flags & MOS8580_FLAG) | ||
180 | ADD ("MOS6581/MOS8580", EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); | ||
181 | else | ||
182 | ADD ("MOS6581", EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); | ||
183 | } | ||
184 | else | ||
185 | { | ||
186 | if (flags & MOS8580_FLAG) | ||
187 | ADD ("MOS8580", EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); | ||
188 | } | ||
189 | |||
190 | return 0; | ||
191 | } | ||