diff --git a/himddump/himddump.c b/himddump/himddump.c index d13c7f8..4bd69a5 100644 --- a/himddump/himddump.c +++ b/himddump/himddump.c @@ -381,7 +381,7 @@ void himd_dumpholes(struct himd * h) } -void get_songinfo(const char *filepath, gchar ** artist, gchar ** title, gchar **album) +void get_songinfo(const char *filepath, struct encstring *artist, struct encstring *title, struct encstring *album) { // printf("DBG: get_songinfo()\n"); struct id3_file * file; @@ -405,13 +405,10 @@ void get_songinfo(const char *filepath, gchar ** artist, gchar ** title, gchar * { if(id3_field_getnstrings(field) > 0) { - //printf("DBG: found artist\n"); - gchar *utf8 = NULL; - - utf8 = (gchar*) id3_ucs4_utf8duplicate( id3_field_getstrings(field,0)); - *artist = utf8; - // fix: utf8 buffer - + //printf("DBG: found artist\n"); + artist->string = (gchar*) id3_ucs4_utf8duplicate( id3_field_getstrings(field,0)); + artist->encoding = HIMD_ENCODING_LATIN1; + artist->must_free = TRUE; /* remember to free it with g_free() */ } } @@ -422,11 +419,9 @@ void get_songinfo(const char *filepath, gchar ** artist, gchar ** title, gchar * if(id3_field_getnstrings(field) > 0) { // printf("DBG: found title\n"); - gchar *utf8 = NULL; - - utf8 = (gchar*) id3_ucs4_utf8duplicate( id3_field_getstrings(field,0)); - *title = utf8; - // fix: utf8 buffer + title->string = (gchar*) id3_ucs4_utf8duplicate( id3_field_getstrings(field,0)); + title->encoding = HIMD_ENCODING_LATIN1; + title->must_free = TRUE; /* remember to free it with g_free() */ } } @@ -437,12 +432,10 @@ void get_songinfo(const char *filepath, gchar ** artist, gchar ** title, gchar * if(id3_field_getnstrings(field) > 0) { //printf("DBG: found album\n"); - gchar *utf8 = NULL; - - utf8 = (gchar*) id3_ucs4_utf8duplicate( id3_field_getstrings(field,0)); - *album = utf8; - // fix: utf8 buffer - } + album->string = (gchar*) id3_ucs4_utf8duplicate( id3_field_getstrings(field,0)); + album->encoding = HIMD_ENCODING_LATIN1; + album->must_free = TRUE; /* remember to free it with g_free() */ + } } id3_file_close(file); @@ -657,7 +650,7 @@ void himd_writemp3(struct himd *h, const char *filepath) GMappedFile * mp3file; unsigned long mp3size; gchar * mp3buffer; - gchar * artist=NULL, * title=NULL, * album=NULL; + struct encstring title ={NULL,0, FALSE}, artist ={NULL,0, FALSE}, album ={NULL,0,FALSE}; int i; unsigned char cid[20] = {0x02, 0x03, 0x00, 0x00}; @@ -730,36 +723,35 @@ void himd_writemp3(struct himd *h, const char *filepath) idx_frag = himd_add_fragment_info(h, &fragment, &status); // END: Add fragment - // Add strings for title, album and artist strings. Retrieve string index numbers. + // Add strings for title, album and artist. Retrieve string index numbers. + // Do not call exit() on errors here, audio data is already stored in atdata file so we have to + // finish writing data to trkidx file to not make the disc useless. gint idx_title=0, idx_album=0, idx_artist=0; - if(title != NULL) { - idx_title = himd_add_string(h, title, STRING_TYPE_TITLE, strlen(title)+1, &status); - if(idx_title < 0) - { - printf("Failed to add title string\n"); - exit(1); - } + if(title.string == NULL) /* reserve string slot for unamed tracks */ + { + title.string = ""; + title.encoding = HIMD_ENCODING_LATIN1; } + idx_title = himd_add_string(h, &title, STRING_TYPE_TITLE, &status); + if(idx_title < 0) printf("Failed to add title string: %s\n", status.statusmsg); - if(album != NULL) { - printf("hello\n"); - idx_album = himd_add_string(h, album, STRING_TYPE_ALBUM, strlen(album)+1, &status); - if(idx_album < 0) - { - printf("Failed to add album string\n"); - exit(1); - } + if(album.string == NULL) /* reserve string slot for unamed tracks */ + { + album.string = ""; + album.encoding = HIMD_ENCODING_LATIN1; } + idx_album = himd_add_string(h, &album, STRING_TYPE_ALBUM, &status); + if(idx_album < 0) printf("Failed to add album string: %s\n", status.statusmsg); - if(artist != NULL) { - idx_artist = himd_add_string(h, artist, STRING_TYPE_ARTIST, strlen(artist)+1, &status); - if(idx_artist < 0) - { - printf("Failed to add artist string\n"); - exit(1); - } + if(artist.string == NULL) /* reserve string slot for unamed tracks */ + { + artist.string = ""; + artist.encoding = HIMD_ENCODING_LATIN1; } + idx_artist = himd_add_string(h, &artist, STRING_TYPE_ARTIST, &status); + if(idx_artist < 0) printf("Failed to add artist string: %s\n", status.statusmsg); + // printf("DBG: idx_title: %d, idx_album: %d, idx_artist: %d\n", idx_title, idx_album, idx_artist); // END: Add strings @@ -806,7 +798,9 @@ void himd_writemp3(struct himd *h, const char *filepath) // Update TRACK-INDEX file with track strings, fragment descriptor and track-descriptor. // himd_write_tifdata(h, &status); - // free(artist); free(album); free(title); + if(title.must_free) g_free(title.string); + if(artist.must_free) g_free(artist.string); + if(album.must_free) g_free(album.string); } int main(int argc, char ** argv) diff --git a/libhimd/himd.h b/libhimd/himd.h index 887f4a9..a873854 100644 --- a/libhimd/himd.h +++ b/libhimd/himd.h @@ -126,6 +126,12 @@ struct himdstring { unsigned int nextstring : 12; }; +struct encstring { + char * string; + unsigned int encoding; + int must_free; +}; + struct himd { /* everything below this line is private, i.e. no API stability. */ char * rootpath; @@ -145,7 +151,7 @@ int himd_open(struct himd * himd, const char * himdroot, struct himderrinfo * st void himd_close(struct himd * himd); char* himd_get_string_raw(struct himd * himd, unsigned int idx, int*type, int* length, struct himderrinfo * status); char* himd_get_string_utf8(struct himd * himd, unsigned int idx, int*type, struct himderrinfo * status); -int himd_add_string(struct himd * himd, char *string, int type, int length, struct himderrinfo * status); +int himd_add_string(struct himd * himd, struct encstring *string, int type, struct himderrinfo * status); void himd_free(void * p); const unsigned char * himd_get_discid(struct himd * himd, struct himderrinfo * status); FILE * himd_open_file(struct himd * himd, const char * fileid); diff --git a/libhimd/trackindex.c b/libhimd/trackindex.c index ffc905f..d498756 100644 --- a/libhimd/trackindex.c +++ b/libhimd/trackindex.c @@ -443,38 +443,30 @@ char* himd_get_string_utf8(struct himd * himd, unsigned int idx, int*type, struc } -int himd_add_string(struct himd * himd, char *string, int type, int length, struct himderrinfo * status) +int himd_add_string(struct himd * himd, struct encstring *string, int type, struct himderrinfo * status) { int curidx, lastidx; int stridx, end_stridx; int nslots=0, rest=0; int idx_freeslot; + int length; unsigned char * linkchunk; unsigned char * freeslot; unsigned char * curchunk; - const char * current_charset; - int strencoding=0; - g_return_val_if_fail(himd != NULL, -1); - g_return_val_if_fail(string != NULL, -1); + g_return_val_if_fail(string != NULL && string->string != NULL, -1); + if(string->encoding != HIMD_ENCODING_LATIN1 && string->encoding != HIMD_ENCODING_UTF16BE && + string->encoding != HIMD_ENCODING_SHIFT_JIS) + set_status_const(status, HIMD_ERROR_UNKNOWN_ENCODING, "unknown encoding"); - if(g_get_charset(¤t_charset)) - strencoding = HIMD_ENCODING_LATIN1; - else if(g_ascii_strncasecmp(current_charset, "UTF16BE", 7) == 0) - strencoding = HIMD_ENCODING_UTF16BE; - else if(g_ascii_strncasecmp(current_charset, "SHIFT_JIS", 9) == 0) - strencoding = HIMD_ENCODING_SHIFT_JIS; - else - set_status_printf(status, HIMD_ERROR_UNKNOWN_ENCODING, - "unknown encoding"); /* how many number of slots to store string in? */ - if(length <= 13) - { - nslots = 1; + if((length = strlen(string->string)) <= 13) /* not strlen(string->string)+1 because we do not */ + { /* need the terminating /0 */ + nslots = 1; } else if(length > 13) { @@ -514,10 +506,10 @@ int himd_add_string(struct himd * himd, char *string, int type, int length, stru if(length <= 13) { curchunk = get_strchunk(himd, curidx); - curchunk[0] = strencoding; + curchunk[0] = string->encoding; setbeword16(&curchunk[14], (type << 12) + 0x00); // type | 00 - memcpy(curchunk+1, &string[0], length); + memcpy(curchunk+1, string->string, length); return idx_freeslot; } @@ -529,10 +521,10 @@ int himd_add_string(struct himd * himd, char *string, int type, int length, stru nslots > 1 && (rest == 0 || rest > 0) */ curchunk = get_strchunk(himd, curidx); - curchunk[0] = strencoding; + curchunk[0] = string->encoding; setbeword16(&curchunk[14], (type << 12) + (curidx+1)); // type | lnk - memcpy(curchunk+1, &string[0], 13); + memcpy(curchunk+1, string->string, 13); curidx += 1; stridx += 1; @@ -547,12 +539,12 @@ int himd_add_string(struct himd * himd, char *string, int type, int length, stru if(curidx == lastidx) { setbeword16(&curchunk[14], (STRING_TYPE_CONTINUATION << 12) + 0); // type | lnk - memcpy(curchunk, &string[stridx*14], (rest == 0 ? 14 : rest) ); + memcpy(curchunk, string->string+stridx*14, (rest == 0 ? 14 : rest) ); break; } setbeword16(&curchunk[14], (STRING_TYPE_CONTINUATION << 12)+(curidx+1)); // type | lnk - memcpy(curchunk, &string[stridx*14], 14); + memcpy(curchunk, string->string+stridx*14, 14); } return idx_freeslot;