diff --git a/lib/driver/cdtext.c b/lib/driver/cdtext.c index dda3a8d2..80bf00c9 100644 --- a/lib/driver/cdtext.c +++ b/lib/driver/cdtext.c @@ -281,7 +281,7 @@ cdtext_get (const cdtext_t *p_cdtext, cdtext_field_t field, track_t track) @param track specifies the track, 0 stands for disc */ const char * -cdtext_get_const(const cdtext_t *p_cdtext, cdtext_field_t field, track_t track) +cdtext_get_const (const cdtext_t *p_cdtext, cdtext_field_t field, track_t track) { if (CDTEXT_FIELD_INVALID == field || NULL == p_cdtext @@ -299,7 +299,7 @@ cdtext_get_const(const cdtext_t *p_cdtext, cdtext_field_t field, track_t track) @param p_cdtext the CD-TEXT object */ cdtext_lang_t -cdtext_get_language(const cdtext_t *p_cdtext) +cdtext_get_language (const cdtext_t *p_cdtext) { if (NULL == p_cdtext) return CDTEXT_LANGUAGE_UNKNOWN; @@ -328,10 +328,10 @@ cdtext_lang_t if (CDTEXT_LANGUAGE_UNKNOWN != p_cdtext->block[i].language_code) avail[j++] = p_cdtext->block[i].language_code; } + return avail; } - /*! Try to select the given language. Select default language if specified is not available or invalid and @@ -343,7 +343,7 @@ cdtext_lang_t @return true on success, false if language is not available */ bool -cdtext_select_language(cdtext_t *p_cdtext, const char *language) +cdtext_select_language (cdtext_t *p_cdtext, const char *language) { cdtext_lang_t lang_id; lang_id = cdtext_is_language(language); @@ -371,6 +371,7 @@ cdtext_select_language(cdtext_t *p_cdtext, const char *language) When the structure is no longer needed, release the resources using cdtext_delete. + */ cdtext_t *cdtext_init (void) @@ -388,6 +389,8 @@ cdtext_t p_cdtext->block[i].track[j].field[k] = NULL; } } + p_cdtext->block[i].genre_code = CDTEXT_GENRE_UNUSED; + p_cdtext->block[i].language_code = CDTEXT_LANGUAGE_UNKNOWN; } p_cdtext->block_i = 0; @@ -405,7 +408,7 @@ cdtext_t @return CDTEXT_INVALID if the given keyword is invalid */ cdtext_field_t -cdtext_is_field(const char *key) +cdtext_is_field (const char *key) { unsigned int i; @@ -450,10 +453,10 @@ cdtext_is_language (const char *lang) */ void cdtext_set (cdtext_t *p_cdtext, cdtext_field_t key, const uint8_t *value, - track_t track, const char *charset) + track_t track, const char *charset) { - if (NULL == value || key == CDTEXT_FIELD_INVALID || 0 > track || 99 < track) - return; + if (NULL == value || key == CDTEXT_FIELD_INVALID || 0 > track || 99 < track) + return; /* free old memory */ if (p_cdtext->block[p_cdtext->block_i].track[track].field[key]) @@ -463,12 +466,11 @@ cdtext_set (cdtext_t *p_cdtext, cdtext_field_t key, const uint8_t *value, if (NULL != charset) { cdio_utf8_t *utf8_str = NULL; cdio_charset_to_utf8((const char*) value, strlen((const char*)value), - &utf8_str, charset); - p_cdtext->block[p_cdtext->block_i].track[track].field[key] = - (char *)utf8_str; + &utf8_str, charset); + p_cdtext->block[p_cdtext->block_i].track[track].field[key] = (char *)utf8_str; } else p_cdtext->block[p_cdtext->block_i].track[track].field[key] = strdup ((const char *)value); - } +} /*! Read a binary CD-TEXT and fill a cdtext struct. @@ -482,226 +484,219 @@ cdtext_set (cdtext_t *p_cdtext, cdtext_field_t key, const uint8_t *value, int cdtext_data_init(cdtext_t *p_cdtext, uint8_t *wdata, size_t i_data) { -/* uint8_t *p_data; */ -/* int j; */ -/* uint8_t buffer[256]; */ -/* int i_buf = 0; */ -/* int i_block; */ -/* int i_seq = 0; */ -/* int i; */ -/* cdtext_blocksize_t blocksize; */ -/* char *charset = NULL; */ + uint8_t *p_data; + int j; + uint8_t buffer[256]; + int i_buf = 0; + int i_block; + int i_seq = 0; + int i; + cdtext_blocksize_t blocksize; + char *charset = NULL; -/* p_data = wdata; */ -/* if (i_data < CDTEXT_LEN_PACK || 0 != i_data % CDTEXT_LEN_PACK) { */ -/* cdio_warn("CD-Text size is not multiple of pack size"); */ -/* return -1; */ -/* } */ + memset( buffer, 0, sizeof(buffer) ); -/* #if 0 */ -/* for(i=0; i < i_data; i++) */ -/* printf("%0x%c", wdata[i], ((i+1) % 18 == 0 ? '\n' : ' ')); */ -/* #endif */ + p_data = wdata; + if (i_data < CDTEXT_LEN_PACK || 0 != i_data % CDTEXT_LEN_PACK) { + cdio_warn("CD-Text size is not multiple of pack size"); + return -1; + } + +#if 0 + for(i=0; i < i_data; i++) + printf("%0x%c", wdata[i], ((i+1) % 18 == 0 ? '\n' : ' ')); +#endif -/* /\* Iterate over blocks *\/ */ -/* i_block = -1; */ -/* while(i_data > 0) { */ -/* cdtext_pack_t pack; */ -/* cdtext_read_pack(&pack, p_data); */ + /* Iterate over blocks */ + i_block = -1; + while(i_data > 0) { + cdtext_pack_t pack; + cdtext_read_pack(&pack, p_data); -/* if (i_block != pack.block || i_seq != pack.seq) { */ -/* cdtext_pack_t tpack; */ -/* i_block = pack.block; */ -/* if (i_block >= CDTEXT_NUM_BLOCKS_MAX) { */ -/* cdio_warn("CD-TEXT: Invalid blocknumber %d.\n", i_block); */ -/* return -1; */ -/* } */ -/* p_cdtext->block_i = i_block; */ -/* i_seq = 0; */ -/* memset( &blocksize, 0, CDTEXT_LEN_BLOCKSIZE); */ + if (i_block != pack.block || i_seq != pack.seq) { + cdtext_pack_t tpack; + i_block = pack.block; + if (i_block >= CDTEXT_NUM_BLOCKS_MAX) { + cdio_warn("CD-TEXT: Invalid blocknumber %d.\n", i_block); + return -1; + } + p_cdtext->block_i = i_block; + i_seq = 0; + memset( &blocksize, 0, CDTEXT_LEN_BLOCKSIZE); -/* /\* first read block size information for sanity checks and encoding *\/ */ -/* for(i=0; i <= i_data-CDTEXT_LEN_PACK; i+=CDTEXT_LEN_PACK) { */ + /* first read block size information for sanity checks and encoding */ + for(i=0; i <= i_data-CDTEXT_LEN_PACK; i+=CDTEXT_LEN_PACK) { -/* if (p_data[i+0] == CDTEXT_PACK_BLOCKSIZE) { */ -/* cdtext_read_pack(&tpack, p_data+i); */ -/* switch (tpack.i_track) { */ -/* case 0: */ -/* blocksize.charcode = tpack.text[0]; */ -/* blocksize.i_first_track = tpack.text[1]; */ -/* blocksize.i_last_track = tpack.text[2]; */ -/* blocksize.copyright = tpack.text[3]; */ -/* blocksize.i_packs[0] = tpack.text[4]; */ -/* blocksize.i_packs[1] = tpack.text[5]; */ -/* blocksize.i_packs[2] = tpack.text[6]; */ -/* blocksize.i_packs[3] = tpack.text[7]; */ -/* blocksize.i_packs[4] = tpack.text[8]; */ -/* blocksize.i_packs[5] = tpack.text[9]; */ -/* blocksize.i_packs[6] = tpack.text[10]; */ -/* blocksize.i_packs[7] = tpack.text[11]; */ -/* break; */ -/* case 1: */ -/* blocksize.i_packs[8] = tpack.text[0]; */ -/* blocksize.i_packs[9] = tpack.text[1]; */ -/* blocksize.i_packs[10] = tpack.text[2]; */ -/* blocksize.i_packs[11] = tpack.text[3]; */ -/* blocksize.i_packs[12] = tpack.text[4]; */ -/* blocksize.i_packs[13] = tpack.text[5]; */ -/* blocksize.i_packs[14] = tpack.text[6]; */ -/* blocksize.i_packs[15] = tpack.text[7]; */ -/* blocksize.lastseq[0] = tpack.text[8]; */ -/* blocksize.lastseq[1] = tpack.text[9]; */ -/* blocksize.lastseq[2] = tpack.text[10]; */ -/* blocksize.lastseq[3] = tpack.text[11]; */ -/* break; */ -/* case 2: */ -/* blocksize.lastseq[4] = tpack.text[0]; */ -/* blocksize.lastseq[5] = tpack.text[1]; */ -/* blocksize.lastseq[6] = tpack.text[2]; */ -/* blocksize.lastseq[7] = tpack.text[3]; */ -/* blocksize.langcode[0] = tpack.text[4]; */ -/* blocksize.langcode[1] = tpack.text[5]; */ -/* blocksize.langcode[2] = tpack.text[6]; */ -/* blocksize.langcode[3] = tpack.text[7]; */ -/* blocksize.langcode[4] = tpack.text[8]; */ -/* blocksize.langcode[5] = tpack.text[9]; */ -/* blocksize.langcode[6] = tpack.text[10]; */ -/* blocksize.langcode[7] = tpack.text[11]; */ -/* break; */ -/* } */ -/* } */ + if (p_data[i+0] == CDTEXT_PACK_BLOCKSIZE) { + cdtext_read_pack(&tpack, p_data+i); + switch (tpack.i_track) { + case 0: + blocksize.charcode = tpack.text[0]; + blocksize.i_first_track = tpack.text[1]; + blocksize.i_last_track = tpack.text[2]; + blocksize.copyright = tpack.text[3]; + blocksize.i_packs[0] = tpack.text[4]; + blocksize.i_packs[1] = tpack.text[5]; + blocksize.i_packs[2] = tpack.text[6]; + blocksize.i_packs[3] = tpack.text[7]; + blocksize.i_packs[4] = tpack.text[8]; + blocksize.i_packs[5] = tpack.text[9]; + blocksize.i_packs[6] = tpack.text[10]; + blocksize.i_packs[7] = tpack.text[11]; + break; + case 1: + blocksize.i_packs[8] = tpack.text[0]; + blocksize.i_packs[9] = tpack.text[1]; + blocksize.i_packs[10] = tpack.text[2]; + blocksize.i_packs[11] = tpack.text[3]; + blocksize.i_packs[12] = tpack.text[4]; + blocksize.i_packs[13] = tpack.text[5]; + blocksize.i_packs[14] = tpack.text[6]; + blocksize.i_packs[15] = tpack.text[7]; + blocksize.lastseq[0] = tpack.text[8]; + blocksize.lastseq[1] = tpack.text[9]; + blocksize.lastseq[2] = tpack.text[10]; + blocksize.lastseq[3] = tpack.text[11]; + break; + case 2: + blocksize.lastseq[4] = tpack.text[0]; + blocksize.lastseq[5] = tpack.text[1]; + blocksize.lastseq[6] = tpack.text[2]; + blocksize.lastseq[7] = tpack.text[3]; + blocksize.langcode[0] = tpack.text[4]; + blocksize.langcode[1] = tpack.text[5]; + blocksize.langcode[2] = tpack.text[6]; + blocksize.langcode[3] = tpack.text[7]; + blocksize.langcode[4] = tpack.text[8]; + blocksize.langcode[5] = tpack.text[9]; + blocksize.langcode[6] = tpack.text[10]; + blocksize.langcode[7] = tpack.text[11]; + break; + } + } + } -/* if(blocksize.i_packs[15] == 3) { */ -/* /\* if there were 3 BLOCKSIZE packs *\/ */ -/* /\* set copyright *\/ */ -/* p_cdtext->block[i_block].copyright = (0x03 == (blocksize.copyright & 0x03)); */ + if(blocksize.i_packs[15] == 3) { + /* if there were 3 BLOCKSIZE packs */ + /* set copyright */ + p_cdtext->block[i_block].copyright = (0x03 == (blocksize.copyright & 0x03)); -/* /\* set Language *\/ */ -/* if(blocksize.langcode[i_block] <= 0x7f) */ -/* p_cdtext->block[i_block].language_code = blocksize.langcode[i_block]; */ + /* set Language */ + if(blocksize.langcode[i_block] <= 0x7f) + p_cdtext->block[i_block].language_code = blocksize.langcode[i_block]; -/* /\* determine encoding *\/ */ -/* switch (blocksize.charcode){ */ -/* case CDTEXT_CHARCODE_ISO_8859_1: */ -/* /\* default *\/ */ -/* charset = (char *) "ISO-8859-1"; */ -/* break; */ -/* case CDTEXT_CHARCODE_ASCII: */ -/* charset = (char *) "ASCII"; */ -/* break; */ -/* case CDTEXT_CHARCODE_SHIFT_JIS: */ -/* charset = (char *) "SHIFT_JIS"; */ -/* break; */ -/* } */ -/* } else { */ -/* cdio_warn("CD-TEXT: No blocksize information available for block %d.\n", i_block); */ -/* return -1; */ -/* } */ + /* determine encoding */ + switch (blocksize.charcode){ + case CDTEXT_CHARCODE_ISO_8859_1: + /* default */ + charset = (char *) "ISO-8859-1"; + break; + case CDTEXT_CHARCODE_ASCII: + charset = (char *) "ASCII"; + break; + case CDTEXT_CHARCODE_SHIFT_JIS: + charset = (char *) "SHIFT_JIS"; + break; + } + } else { + cdio_warn("CD-TEXT: No blocksize information available for block %d.\n", i_block); + return -1; + } -/* } */ + } -/* cdtext_read_pack(&pack, p_data); */ + cdtext_read_pack(&pack, p_data); -/* #ifndef _CDTEXT_DBCC */ -/* if ( pack.db_chars ) { */ -/* cdio_warn("CD-TEXT: Double-byte characters not supported"); */ -/* return -1; */ -/* } */ -/* #endif */ +#ifndef _CDTEXT_DBCC + if ( pack.db_chars ) { + cdio_warn("CD-TEXT: Double-byte characters not supported"); + return -1; + } +#endif -/* /\* read text packs first *\/ */ -/* j = 0; */ -/* switch (pack.type) { */ -/* case CDTEXT_PACK_GENRE: */ -/* /\* If pack.text starts with an unprintable character, it is likely to bethe genre_code. */ -/* * While the specification requires the first GENRE pack to start with te 2 byte genre code, */ -/* * it is not specific about the following ones. *\/ */ -/* if (pack.text[0] <= 31) { */ -/* j = 2; */ -/* if (CDTEXT_GENRE_UNUSED == p_cdtext->block[i_block].genre_code) */ -/* p_cdtext->block[i_block].genre_code = CDTEXT_GET_LEN16(pack.text); */ -/* } */ -/* case CDTEXT_PACK_TITLE: */ -/* case CDTEXT_PACK_PERFORMER: */ -/* case CDTEXT_PACK_SONGWRITER: */ -/* case CDTEXT_PACK_COMPOSER: */ -/* case CDTEXT_PACK_ARRANGER: */ -/* case CDTEXT_PACK_MESSAGE: */ -/* case CDTEXT_PACK_DISCID: */ -/* case CDTEXT_PACK_UPC: */ -/* while (j < CDTEXT_LEN_TEXTDATA) { */ -/* /\* not terminated *\/ */ -/* if (pack.text[j] != 0 || (pack.db_chars && pack.text[j+1] != 0)) { */ -/* buffer[i_buf++] = pack.text[j]; */ -/* if(pack.db_chars) */ -/* buffer[i_buf++] = pack.text[j+1]; */ -/* } else if(i_buf > 1) { */ -/* buffer[i_buf++] = 0; */ -/* if(pack.db_chars) */ -/* buffer[i_buf++] = 0; */ + /* read text packs first */ + j = 0; + switch (pack.type) { + case CDTEXT_PACK_GENRE: + /* If pack.text starts with an unprintable character, it is likely to be the genre_code. + * While the specification requires the first GENRE pack to start with the 2 byte genre code, + * it is not specific about the following ones. */ + if (pack.text[0] <= 31) { + j = 2; + if (CDTEXT_GENRE_UNUSED == p_cdtext->block[i_block].genre_code) + p_cdtext->block[i_block].genre_code = CDTEXT_GET_LEN16(pack.text); + } + case CDTEXT_PACK_TITLE: + case CDTEXT_PACK_PERFORMER: + case CDTEXT_PACK_SONGWRITER: + case CDTEXT_PACK_COMPOSER: + case CDTEXT_PACK_ARRANGER: + case CDTEXT_PACK_MESSAGE: + case CDTEXT_PACK_DISCID: + case CDTEXT_PACK_UPC: + while (j < CDTEXT_LEN_TEXTDATA) { + /* not terminated */ + if (pack.text[j] != 0 || (pack.db_chars && pack.text[j+1] != 0)) { + buffer[i_buf++] = pack.text[j]; + if(pack.db_chars) + buffer[i_buf++] = pack.text[j+1]; + } else if(i_buf > 1) { + buffer[i_buf++] = 0; + if(pack.db_chars) + buffer[i_buf++] = 0; -/* switch (pack.type) { */ -/* case CDTEXT_PACK_TITLE: */ -/* cdtext_set(p_cdtext, CDTEXT_FIELD_TITLE, buffer, */ -/* pack.i_track, charset); */ -/* break; */ -/* case CDTEXT_PACK_PERFORMER: */ -/* cdtext_set(p_cdtext, CDTEXT_FIELD_PERFORMER, buffer, */ -/* pack.i_track, charset); */ -/* break; */ -/* case CDTEXT_PACK_SONGWRITER: */ -/* cdtext_set(p_cdtext, CDTEXT_FIELD_SONGWRITER, buffer, */ -/* pack.i_track, charset); */ -/* break; */ -/* case CDTEXT_PACK_COMPOSER: */ -/* cdtext_set(p_cdtext, CDTEXT_FIELD_COMPOSER, buffer, */ -/* pack.i_track, charset); */ -/* break; */ -/* case CDTEXT_PACK_ARRANGER: */ -/* cdtext_set(p_cdtext, CDTEXT_FIELD_ARRANGER, buffer, */ -/* pack.i_track, charset); */ -/* break; */ -/* case CDTEXT_PACK_MESSAGE: */ -/* cdtext_set(p_cdtext, CDTEXT_FIELD_MESSAGE, buffer, */ -/* pack.i_track,charset); */ -/* break; */ -/* case CDTEXT_PACK_DISCID: */ -/* if (pack.i_track == 0) */ -/* cdtext_set(p_cdtext, CDTEXT_FIELD_DISCID, buffer, */ -/* pack.i_track, NULL); */ -/* break; */ -/* case CDTEXT_PACK_GENRE: */ -/* cdtext_set(p_cdtext, CDTEXT_FIELD_GENRE, buffer, */ -/* pack.i_track, "ASCII"); */ -/* break; */ -/* case CDTEXT_PACK_UPC: */ -/* if (pack.i_track == 0) */ -/* cdtext_set(p_cdtext, CDTEXT_FIELD_UPC_EAN, buffer, */ -/* pack.i_track, "ASCII"); */ -/* else */ -/* cdtext_set(p_cdtext, CDTEXT_FIELD_ISRC, buffer, */ -/* pack.i_track, "ISO-8859-1"); */ -/* break; */ -/* } */ -/* i_buf = 0; */ + switch (pack.type) { + case CDTEXT_PACK_TITLE: + cdtext_set(p_cdtext, CDTEXT_FIELD_TITLE, buffer, pack.i_track, charset); + break; + case CDTEXT_PACK_PERFORMER: + cdtext_set(p_cdtext, CDTEXT_FIELD_PERFORMER, buffer, pack.i_track, charset); + break; + case CDTEXT_PACK_SONGWRITER: + cdtext_set(p_cdtext, CDTEXT_FIELD_SONGWRITER, buffer, pack.i_track, charset); + break; + case CDTEXT_PACK_COMPOSER: + cdtext_set(p_cdtext, CDTEXT_FIELD_COMPOSER, buffer, pack.i_track, charset); + break; + case CDTEXT_PACK_ARRANGER: + cdtext_set(p_cdtext, CDTEXT_FIELD_ARRANGER, buffer, pack.i_track, charset); + break; + case CDTEXT_PACK_MESSAGE: + cdtext_set(p_cdtext, CDTEXT_FIELD_MESSAGE, buffer, pack.i_track, charset); + break; + case CDTEXT_PACK_DISCID: + if (pack.i_track == 0) + cdtext_set(p_cdtext, CDTEXT_FIELD_DISCID, buffer, pack.i_track, NULL); + break; + case CDTEXT_PACK_GENRE: + cdtext_set(p_cdtext, CDTEXT_FIELD_GENRE, buffer, pack.i_track, "ASCII"); + break; + case CDTEXT_PACK_UPC: + if (pack.i_track == 0) + cdtext_set(p_cdtext, CDTEXT_FIELD_UPC_EAN, buffer, pack.i_track, "ASCII"); + else + cdtext_set(p_cdtext, CDTEXT_FIELD_ISRC, buffer, pack.i_track, "ISO-8859-1"); + break; + } + i_buf = 0; -/* } */ -/* if (pack.db_chars) */ -/* j+=2; */ -/* else */ -/* j+=1; */ -/* } */ -/* break; */ -/* } */ -/* /\* This would be the right place to parse TOC and TOC2 fields. *\/ */ + } + if (pack.db_chars) + j+=2; + else + j+=1; + } + break; + } + /* This would be the right place to parse TOC and TOC2 fields. */ -/* i_seq++; */ -/* i_data-=CDTEXT_LEN_PACK; */ -/* p_data+=CDTEXT_LEN_PACK; */ -/* } /\* end of while loop *\/ */ + i_seq++; + i_data-=CDTEXT_LEN_PACK; + p_data+=CDTEXT_LEN_PACK; + } /* end of while loop */ -/* p_cdtext->block_i = 0; */ + p_cdtext->block_i = 0; return 0; } diff --git a/lib/driver/image/bincue.c b/lib/driver/image/bincue.c index e17e09ec..d58026f5 100644 --- a/lib/driver/image/bincue.c +++ b/lib/driver/image/bincue.c @@ -335,10 +335,11 @@ parse_cuefile (_img_private_t *cd, const char *psz_cue_name) if(NULL != (psz_field = strtok (NULL, "\"\t\n\r"))) { if (cd) { uint8_t cdt_data[CDTEXT_LEN_BINARY_MAX+4]; + uint8_t *ptr; int size; CdioDataSource_t *source; - const char *dirname = cdio_dirname(psz_cue_name); - const char *psz_filename = cdio_abspath (dirname, psz_field); + const char *dirname = cdio_dirname(psz_cue_name); + const char *psz_filename = cdio_abspath (dirname, psz_field); if(NULL == (source = cdio_stdio_new(psz_filename))) { cdio_log (log_level, "%s line %d: can't open file `%s' for reading", psz_cue_name, i_line, psz_field); @@ -347,16 +348,18 @@ parse_cuefile (_img_private_t *cd, const char *psz_cue_name) size = cdio_stream_read(source, cdt_data, CDTEXT_LEN_BINARY_MAX, 1); if (size < 5) { - cdio_log (log_level, - "%s line %d: file `%s' is too small to contain CD-TEXT", - psz_cue_name, i_line, (char *) psz_filename); + cdio_log (log_level, "%s line %d: file `%s' is too small to contain CD-TEXT", + psz_cue_name, i_line, (char *) psz_filename); goto err_exit; } /* cut header */ if (cdt_data[0] > 0x80) { + ptr = &cdt_data[4]; size -= 4; } + else + ptr = cdt_data; /* ignore trailing 0 */ if (1 == size % 18)