libextractor

GNU libextractor
Log | Files | Refs | Submodules | README | LICENSE

commit 448727f8d0e3ac5e675d6b822f4cabde048b0538
parent 258ee544331018ddb3790feecfd674a1b1839c71
Author: Toni Ruottu <toni.ruottu@helsinki.fi>
Date:   Sun,  7 Jan 2007 15:50:24 +0000

Rewrote the sid extractor for clarity.

Diffstat:
Msrc/plugins/sidextractor.c | 364++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
1 file changed, 212 insertions(+), 152 deletions(-)

diff --git a/src/plugins/sidextractor.c b/src/plugins/sidextractor.c @@ -1,21 +1,22 @@ /* - This file is part of libextractor. - (C) 2006 Toni Ruottu - - libextractor is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 2, or (at your - option) any later version. - - libextractor is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with libextractor; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. + * This file is part of libextractor. + * (C) 2006, 2007 Toni Ruottu + * + * libextractor is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * libextractor is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with libextractor; see the file COPYING. If not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * */ #include "platform.h" @@ -23,17 +24,65 @@ #include "convert.h" -static struct EXTRACTOR_Keywords * -addkword(EXTRACTOR_KeywordList *oldhead, - const char * phrase, - EXTRACTOR_KeywordType type) { - EXTRACTOR_KeywordList * keyword; +#define SID1_HEADER_SIZE 0x76 +#define SID2_HEADER_SIZE 0x7c + +/* flags */ + +#define MUSPLAYER_FLAG 0x01 +#define PLAYSID_FLAG 0x02 +#define PAL_FLAG 0x04 +#define NTSC_FLAG 0x08 +#define MOS6581_FLAG 0x10 +#define MOS8580_FLAG 0x20 + +typedef char sidwrd[ 2 ]; +typedef char sidlongwrd[ 4 ]; + +struct header +{ + char magicid[ 4 ]; + sidwrd sidversion; + sidwrd dataoffset; + sidwrd loadaddr; + sidwrd initaddr; + sidwrd playaddr; + sidwrd songs; + sidwrd firstsong; + sidlongwrd speed; + char title[ 32 ]; + char artist[ 32 ]; + char copyright[ 32 ]; + sidwrd flags; /* version 2 specific fields start */ + char startpage; + char pagelength; + sidwrd reserved; +}; + +int sidword( sidwrd data ) +{ + int value = + ( unsigned char ) data[ 0 ] * 0x100 + + ( unsigned char ) data[ 1 ]; + + return( value ); + +} - keyword = malloc(sizeof(EXTRACTOR_KeywordList)); - keyword->next = oldhead; - keyword->keyword = strdup(phrase); - keyword->keywordType = type; - return keyword; +static struct EXTRACTOR_Keywords * addkword +( + EXTRACTOR_KeywordList *oldhead, + const char * phrase, + EXTRACTOR_KeywordType type +) +{ + EXTRACTOR_KeywordList * keyword; + + keyword = malloc( sizeof( EXTRACTOR_KeywordList ) ); + keyword->next = oldhead; + keyword->keyword = strdup( phrase ); + keyword->keywordType = type; + return( keyword ); } @@ -41,129 +90,140 @@ addkword(EXTRACTOR_KeywordList *oldhead, * * This plugin is based on the nsf extractor * - * */ -struct EXTRACTOR_Keywords * -libextractor_sid_extract(const char * filename, - char * data, - size_t size, - struct EXTRACTOR_Keywords * prev) { - int i, version; - char album[33]; - char artist[33]; - char copyright[33]; - char songs[32]; - char startingsong[32]; - - - /* Check header size and "magic" id bytes */ - - if - ( - size < 0x76 || - ( data[0] != 'P' && data[0] != 'R' ) || - data[1] != 'S' || - data[2] != 'I' || - data[3] != 'D' - ) - { - return prev; - } - - - /* Mime-type */ - - prev = addkword(prev, "audio/prs.sid", EXTRACTOR_MIMETYPE); - - /* Version of SID format */ - - version = data[4] * 0x100 + data[5]; - sprintf( startingsong, "%d", version ); - prev = addkword(prev, startingsong, EXTRACTOR_FORMAT_VERSION); - - - /* Get song count */ - - sprintf( songs, "%d", data[0x0e] * 0x100 + data[0x0f] ); - prev = addkword(prev, songs, EXTRACTOR_SONG_COUNT); - - - /* Get number of the first song to be played */ - - sprintf( startingsong, "%d", data[0x10] * 0x100 + data[0x11] ); - prev = addkword(prev, startingsong, EXTRACTOR_STARTING_SONG); - - - /* Parse album, artist, copyright fields */ - - for( i = 0; i < 32; i++ ) - { - album[i] = data[ 0x16 + i ]; - artist[i] = data[ 0x36 + i ]; - copyright[i] = data[ 0x56 + i ]; - } - - album[32] = '\0'; - artist[32] = '\0'; - copyright[32] = '\0'; - - prev = addkword(prev, album, EXTRACTOR_ALBUM); - prev = addkword(prev, artist, EXTRACTOR_ARTIST); - prev = addkword(prev, copyright, EXTRACTOR_COPYRIGHT); - - - if( version < 2 || size < 0x7c ) - { - return prev; - } - - /* Version 2 specific options follow - * - * Note: Had some troubles understanding specification - * on the flags in version 2. I hope this is correct. - * - */ - - /* PAL or NTSC */ - - if( data[0x77] & 16 ) - { - if( data[0x77] & 32 ) - { - prev = addkword(prev, "PAL/NTSC", EXTRACTOR_TELEVISION_SYSTEM); - } - else - { - prev = addkword(prev, "PAL", EXTRACTOR_TELEVISION_SYSTEM); - } - } - else - { - if( data[0x77] & 32 ) - { - prev = addkword(prev, "NTSC", EXTRACTOR_TELEVISION_SYSTEM); - } - } - - /* Detect SID Chips suitable for play the files */ - - if( data[0x77] & 4 ) - { - if( data[0x77] & 8 ) - { - prev = addkword(prev, "MOS6581/MOS8580", EXTRACTOR_HARDWARE_DEPENDENCY); - } - else - { - prev = addkword(prev, "MOS6581", EXTRACTOR_HARDWARE_DEPENDENCY); - } - } - else - { - if( data[0x77] & 8 ) - { - prev = addkword(prev, "MOS8580", EXTRACTOR_HARDWARE_DEPENDENCY); - } - } - - return prev; + */ +struct EXTRACTOR_Keywords * libextractor_sid_extract +( + const char * filename, + char * data, + size_t size, + struct EXTRACTOR_Keywords * prev +) +{ + unsigned int flags; + int i, version; + char album[ 33 ]; + char artist[ 33 ]; + char copyright[ 33 ]; + char songs[ 32 ]; + char startingsong[ 32 ]; + char sidversion[ 32 ]; + struct header *head; + + /* Check header size */ + + if( size < SID1_HEADER_SIZE ) + { + return( prev ); + } + + head = ( struct header * ) data; + + /* Check "magic" id bytes */ + + if + ( + memcmp( head->magicid, "PSID", 4 ) && + memcmp( head->magicid, "RSID", 4 ) + ) + { + return( prev ); + } + + + /* Mime-type */ + + prev = addkword( prev, "audio/prs.sid", EXTRACTOR_MIMETYPE ); + + + /* Version of SID format */ + + version = sidword( head->sidversion ); + sprintf( sidversion, "%d", version ); + prev = addkword( prev, sidversion, EXTRACTOR_FORMAT_VERSION ); + + + /* Get song count */ + + sprintf( songs, "%d", sidword( head->songs ) ); + prev = addkword( prev, songs, EXTRACTOR_SONG_COUNT ); + + + /* Get number of the first song to be played */ + + sprintf( startingsong, "%d", sidword( head->firstsong ) ); + prev = addkword( prev, startingsong, EXTRACTOR_STARTING_SONG ); + + + /* name, artist, copyright fields */ + + memcpy( &album, head->title, 32 ); + memcpy( &artist, head->artist, 32 ); + memcpy( &copyright, head->copyright, 32 ); + + album[ 32 ] = '\0'; + artist[ 32 ] = '\0'; + copyright[ 32 ] = '\0'; + + prev = addkword( prev, album, EXTRACTOR_ALBUM ); + prev = addkword( prev, artist, EXTRACTOR_ARTIST ); + prev = addkword( prev, copyright, EXTRACTOR_COPYRIGHT ); + + + if( version < 2 || size < SID2_HEADER_SIZE ) + { + return( prev ); + } + + /* Version 2 specific options follow + * + * Note: Had some troubles understanding specification + * on the flags in version 2. I hope this is correct. + * + */ + + flags = sidword( head->flags ); + + /* PAL or NTSC */ + + if( flags & PAL_FLAG ) + { + if( flags & NTSC_FLAG ) + { + prev = addkword( prev, "PAL/NTSC", EXTRACTOR_TELEVISION_SYSTEM ); + } + else + { + prev = addkword( prev, "PAL", EXTRACTOR_TELEVISION_SYSTEM ); + } + } + else + { + if( flags & NTSC_FLAG ) + { + prev = addkword( prev, "NTSC", EXTRACTOR_TELEVISION_SYSTEM ); + } + } + + /* Detect SID Chips suitable for play the files */ + + if( flags & MOS6581_FLAG ) + { + if( flags & MOS8580_FLAG ) + { + prev = addkword( prev, "MOS6581/MOS8580", EXTRACTOR_HARDWARE_DEPENDENCY ); + } + else + { + prev = addkword( prev, "MOS6581", EXTRACTOR_HARDWARE_DEPENDENCY ); + } + } + else + { + if( flags & MOS8580_FLAG ) + { + prev = addkword( prev, "MOS8580", EXTRACTOR_HARDWARE_DEPENDENCY ); + } + } + + return( prev ); }