diff options
Diffstat (limited to 'src/plugins/nsfe_extractor.c')
-rw-r--r-- | src/plugins/nsfe_extractor.c | 193 |
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 | */ |
83 | static char * | 83 | static char * |
84 | nsfestring (const char *data, | 84 | nsfestring (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 | */ |
169 | static int | 178 | static int |
170 | info_extract (struct EXTRACTOR_ExtractContext *ec, | 179 | info_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 | */ |
237 | static int | 246 | static int |
238 | tlbl_extract (struct EXTRACTOR_ExtractContext *ec, | 247 | tlbl_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 | */ |
275 | static int | 284 | static int |
276 | auth_extract (struct EXTRACTOR_ExtractContext *ec, | 285 | auth_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 */ |