aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/nsfe_extractor.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/nsfe_extractor.c')
-rw-r--r--src/plugins/nsfe_extractor.c193
1 files changed, 101 insertions, 92 deletions
diff --git a/src/plugins/nsfe_extractor.c b/src/plugins/nsfe_extractor.c
index 2f6ab8b..36ba115 100644
--- a/src/plugins/nsfe_extractor.c
+++ b/src/plugins/nsfe_extractor.c
@@ -63,10 +63,10 @@ nsfeuint (const char *data)
63 int i; 63 int i;
64 64
65 for (i = 3; i > 0; i--) 65 for (i = 3; i > 0; i--)
66 { 66 {
67 value += (unsigned char) data[i]; 67 value += (unsigned char) data[i];
68 value *= 0x100; 68 value *= 0x100;
69 } 69 }
70 value += (unsigned char) data[0]; 70 value += (unsigned char) data[0];
71 return value; 71 return value;
72} 72}
@@ -82,14 +82,14 @@ nsfeuint (const char *data)
82 */ 82 */
83static char * 83static char *
84nsfestring (const char *data, 84nsfestring (const char *data,
85 size_t size) 85 size_t size)
86{ 86{
87 char *s; 87 char *s;
88 size_t length; 88 size_t length;
89 89
90 length = 0; 90 length = 0;
91 while ( (length < size) && 91 while ( (length < size) &&
92 (data[length] != '\0') ) 92 (data[length] != '\0') )
93 length++; 93 length++;
94 if (NULL == (s = malloc (length + 1))) 94 if (NULL == (s = malloc (length + 1)))
95 return NULL; 95 return NULL;
@@ -105,7 +105,11 @@ nsfestring (const char *data,
105 * @param s metadata value as UTF8 105 * @param s metadata value as UTF8
106 * @param t metadata type to use 106 * @param t metadata type to use
107 */ 107 */
108#define ADD(s,t) do { if (0 != ec->proc (ec->cls, "nsfe", t, EXTRACTOR_METAFORMAT_UTF8, "text/plain", s, strlen (s) + 1)) return 1; } while (0) 108#define ADD(s,t) do { if (0 != ec->proc (ec->cls, "nsfe", t, \
109 EXTRACTOR_METAFORMAT_UTF8, \
110 "text/plain", s, strlen (s) \
111 + 1)) return 1; \
112} while (0)
109 113
110 114
111/** 115/**
@@ -114,7 +118,12 @@ nsfestring (const char *data,
114 * @param s metadata value as UTF8, free at the end 118 * @param s metadata value as UTF8, free at the end
115 * @param t metadata type to use 119 * @param t metadata type to use
116 */ 120 */
117#define ADDF(s,t) do { if (0 != ec->proc (ec->cls, "nsfe", t, EXTRACTOR_METAFORMAT_UTF8, "text/plain", s, strlen (s) + 1)) { free (s); return 1; } free (s); } while (0) 121#define ADDF(s,t) do { if (0 != ec->proc (ec->cls, "nsfe", t, \
122 EXTRACTOR_METAFORMAT_UTF8, \
123 "text/plain", s, strlen (s) \
124 + 1)) { free (s); \
125 return 1; \
126 } free (s); } while (0)
118 127
119 128
120/** 129/**
@@ -168,7 +177,7 @@ struct infochunk
168 */ 177 */
169static int 178static int
170info_extract (struct EXTRACTOR_ExtractContext *ec, 179info_extract (struct EXTRACTOR_ExtractContext *ec,
171 uint32_t size) 180 uint32_t size)
172{ 181{
173 void *data; 182 void *data;
174 const struct infochunk *ichunk; 183 const struct infochunk *ichunk;
@@ -178,22 +187,22 @@ info_extract (struct EXTRACTOR_ExtractContext *ec,
178 return 0; 187 return 0;
179 if ((ssize_t) size > 188 if ((ssize_t) size >
180 ec->read (ec->cls, 189 ec->read (ec->cls,
181 &data, 190 &data,
182 size)) 191 size))
183 return 1; 192 return 1;
184 ichunk = data; 193 ichunk = data;
185 194
186 if (0 != (ichunk->tvflags & DUAL_FLAG)) 195 if (0 != (ichunk->tvflags & DUAL_FLAG))
187 { 196 {
188 ADD ("PAL/NTSC", EXTRACTOR_METATYPE_BROADCAST_TELEVISION_SYSTEM); 197 ADD ("PAL/NTSC", EXTRACTOR_METATYPE_BROADCAST_TELEVISION_SYSTEM);
189 } 198 }
190 else 199 else
191 { 200 {
192 if (0 != (ichunk->tvflags & PAL_FLAG)) 201 if (0 != (ichunk->tvflags & PAL_FLAG))
193 ADD ("PAL", EXTRACTOR_METATYPE_BROADCAST_TELEVISION_SYSTEM); 202 ADD ("PAL", EXTRACTOR_METATYPE_BROADCAST_TELEVISION_SYSTEM);
194 else 203 else
195 ADD ("NTSC", EXTRACTOR_METATYPE_BROADCAST_TELEVISION_SYSTEM); 204 ADD ("NTSC", EXTRACTOR_METATYPE_BROADCAST_TELEVISION_SYSTEM);
196 } 205 }
197 206
198 if (0 != (ichunk->chipflags & VRCVI_FLAG)) 207 if (0 != (ichunk->chipflags & VRCVI_FLAG))
199 ADD ("VRCVI", EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); 208 ADD ("VRCVI", EXTRACTOR_METATYPE_TARGET_ARCHITECTURE);
@@ -209,19 +218,19 @@ info_extract (struct EXTRACTOR_ExtractContext *ec,
209 ADD ("Sunsoft FME-07", EXTRACTOR_METATYPE_TARGET_ARCHITECTURE); 218 ADD ("Sunsoft FME-07", EXTRACTOR_METATYPE_TARGET_ARCHITECTURE);
210 219
211 if (size < sizeof (struct infochunk)) 220 if (size < sizeof (struct infochunk))
212 { 221 {
213 ADD ("1", EXTRACTOR_METATYPE_SONG_COUNT); 222 ADD ("1", EXTRACTOR_METATYPE_SONG_COUNT);
214 return 0; 223 return 0;
215 } 224 }
216 snprintf (songs, 225 snprintf (songs,
217 sizeof (songs), 226 sizeof (songs),
218 "%d", 227 "%d",
219 ichunk->songs); 228 ichunk->songs);
220 ADD (songs, EXTRACTOR_METATYPE_SONG_COUNT); 229 ADD (songs, EXTRACTOR_METATYPE_SONG_COUNT);
221 snprintf (songs, 230 snprintf (songs,
222 sizeof (songs), 231 sizeof (songs),
223 "%d", 232 "%d",
224 ichunk->firstsong); 233 ichunk->firstsong);
225 ADD (songs, EXTRACTOR_METATYPE_STARTING_SONG); 234 ADD (songs, EXTRACTOR_METATYPE_STARTING_SONG);
226 return 0; 235 return 0;
227} 236}
@@ -236,7 +245,7 @@ info_extract (struct EXTRACTOR_ExtractContext *ec,
236 */ 245 */
237static int 246static int
238tlbl_extract (struct EXTRACTOR_ExtractContext *ec, 247tlbl_extract (struct EXTRACTOR_ExtractContext *ec,
239 uint32_t size) 248 uint32_t size)
240{ 249{
241 char *title; 250 char *title;
242 ssize_t left; 251 ssize_t left;
@@ -246,21 +255,21 @@ tlbl_extract (struct EXTRACTOR_ExtractContext *ec,
246 255
247 if ((ssize_t) size > 256 if ((ssize_t) size >
248 ec->read (ec->cls, 257 ec->read (ec->cls,
249 &data, 258 &data,
250 size)) 259 size))
251 return 1; 260 return 1;
252 cdata = data; 261 cdata = data;
253 262
254 left = size; 263 left = size;
255 while (left > 0) 264 while (left > 0)
256 { 265 {
257 title = nsfestring (&cdata[size - left], left); 266 title = nsfestring (&cdata[size - left], left);
258 if (NULL == title) 267 if (NULL == title)
259 return 0; 268 return 0;
260 length = strlen (title) + 1; 269 length = strlen (title) + 1;
261 ADDF (title, EXTRACTOR_METATYPE_TITLE); 270 ADDF (title, EXTRACTOR_METATYPE_TITLE);
262 left -= length; 271 left -= length;
263 } 272 }
264 return 0; 273 return 0;
265} 274}
266 275
@@ -274,7 +283,7 @@ tlbl_extract (struct EXTRACTOR_ExtractContext *ec,
274 */ 283 */
275static int 284static int
276auth_extract (struct EXTRACTOR_ExtractContext *ec, 285auth_extract (struct EXTRACTOR_ExtractContext *ec,
277 uint32_t size) 286 uint32_t size)
278{ 287{
279 char *album; 288 char *album;
280 char *artist; 289 char *artist;
@@ -288,37 +297,37 @@ auth_extract (struct EXTRACTOR_ExtractContext *ec,
288 return 0; 297 return 0;
289 if ((ssize_t) size > 298 if ((ssize_t) size >
290 ec->read (ec->cls, 299 ec->read (ec->cls,
291 &data, 300 &data,
292 size)) 301 size))
293 return 1; 302 return 1;
294 cdata = data; 303 cdata = data;
295 304
296 album = nsfestring (&cdata[size - left], left); 305 album = nsfestring (&cdata[size - left], left);
297 if (NULL != album) 306 if (NULL != album)
298 { 307 {
299 left -= (strlen (album) + 1); 308 left -= (strlen (album) + 1);
300 ADDF (album, EXTRACTOR_METATYPE_ALBUM); 309 ADDF (album, EXTRACTOR_METATYPE_ALBUM);
301 if (left < 1) 310 if (left < 1)
302 return 0; 311 return 0;
303 } 312 }
304 313
305 artist = nsfestring (&cdata[size - left], left); 314 artist = nsfestring (&cdata[size - left], left);
306 if (NULL != artist) 315 if (NULL != artist)
307 { 316 {
308 left -= (strlen (artist) + 1); 317 left -= (strlen (artist) + 1);
309 ADDF (artist, EXTRACTOR_METATYPE_ARTIST); 318 ADDF (artist, EXTRACTOR_METATYPE_ARTIST);
310 if (left < 1) 319 if (left < 1)
311 return 0; 320 return 0;
312 } 321 }
313 322
314 copyright = nsfestring (&cdata[size - left], left); 323 copyright = nsfestring (&cdata[size - left], left);
315 if (NULL != copyright) 324 if (NULL != copyright)
316 { 325 {
317 left -= (strlen (copyright) + 1); 326 left -= (strlen (copyright) + 1);
318 ADDF (copyright, EXTRACTOR_METATYPE_COPYRIGHT); 327 ADDF (copyright, EXTRACTOR_METATYPE_COPYRIGHT);
319 if (left < 1) 328 if (left < 1)
320 return 0; 329 return 0;
321 } 330 }
322 ripper = nsfestring (&cdata[size - left], left); 331 ripper = nsfestring (&cdata[size - left], left);
323 if (NULL != ripper) 332 if (NULL != ripper)
324 ADDF (ripper, EXTRACTOR_METATYPE_RIPPER); 333 ADDF (ripper, EXTRACTOR_METATYPE_RIPPER);
@@ -345,46 +354,46 @@ EXTRACTOR_nsfe_extract_method (struct EXTRACTOR_ExtractContext *ec)
345 354
346 if ((ssize_t) sizeof (struct header) > 355 if ((ssize_t) sizeof (struct header) >
347 ec->read (ec->cls, 356 ec->read (ec->cls,
348 &data, 357 &data,
349 sizeof (struct header))) 358 sizeof (struct header)))
350 return; 359 return;
351 head = data; 360 head = data;
352 if (0 != memcmp (head->magicid, "NSFE", 4)) 361 if (0 != memcmp (head->magicid, "NSFE", 4))
353 return; 362 return;
354 363
355 if (0 != ec->proc (ec->cls, 364 if (0 != ec->proc (ec->cls,
356 "nsfe", 365 "nsfe",
357 EXTRACTOR_METATYPE_MIMETYPE, 366 EXTRACTOR_METATYPE_MIMETYPE,
358 EXTRACTOR_METAFORMAT_UTF8, 367 EXTRACTOR_METAFORMAT_UTF8,
359 "text/plain", 368 "text/plain",
360 "audio/x-nsfe", 369 "audio/x-nsfe",
361 strlen ("audio/x-nsfe") + 1)) 370 strlen ("audio/x-nsfe") + 1))
362 return; 371 return;
363 off = sizeof (struct header); 372 off = sizeof (struct header);
364 ret = 0; 373 ret = 0;
365 while (0 == ret) 374 while (0 == ret)
366 { 375 {
367 if (off != ec->seek (ec->cls, 376 if (off != ec->seek (ec->cls,
368 off, 377 off,
369 SEEK_SET)) 378 SEEK_SET))
370 break; 379 break;
371 if (8 > 380 if (8 >
372 ec->read (ec->cls, 381 ec->read (ec->cls,
373 &data, 382 &data,
374 8)) 383 8))
375 break; 384 break;
376 chunksize = nsfeuint (data); 385 chunksize = nsfeuint (data);
377 if (off + chunksize + 8LLU <= off) 386 if (off + chunksize + 8LLU <= off)
378 break; /* protect against looping */ 387 break; /* protect against looping */
379 off += 8LLU + chunksize; 388 off += 8LLU + chunksize;
380 if (0 == memcmp (data + 4, "INFO", 4)) 389 if (0 == memcmp (data + 4, "INFO", 4))
381 ret = info_extract (ec, chunksize); 390 ret = info_extract (ec, chunksize);
382 else if (0 == memcmp (data + 4, "auth", 4)) 391 else if (0 == memcmp (data + 4, "auth", 4))
383 ret = auth_extract (ec, chunksize); 392 ret = auth_extract (ec, chunksize);
384 else if (0 == memcmp (data + 4, "tlbl", 4)) 393 else if (0 == memcmp (data + 4, "tlbl", 4))
385 ret = tlbl_extract (ec, chunksize); 394 ret = tlbl_extract (ec, chunksize);
386 /* Ignored chunks: DATA, NEND, plst, time, fade, BANK */ 395 /* Ignored chunks: DATA, NEND, plst, time, fade, BANK */
387 } 396 }
388} 397}
389 398
390/* end of nsfe_extractor.c */ 399/* end of nsfe_extractor.c */