From 54213286cda17b8fb0dc752b5930c10a7d107f5d Mon Sep 17 00:00:00 2001 From: Kevin Chabowski Date: Tue, 25 Dec 2012 12:09:33 +0100 Subject: [PATCH 1/2] himd_set_track_label implemented * himd_set_track_label can set the title/artist/album label of a track * Also added himd_modify_track_info which makes it a bit easier to modify track infos of already existing tracks. * Nice side-effect: himdcli can now set title/artist/album of tracks. --- himdcli/himdcli.c | 49 ++++++++++++---- libhimd/himd.h | 16 ++++++ libhimd/trackindex.c | 155 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 209 insertions(+), 11 deletions(-) diff --git a/himdcli/himdcli.c b/himdcli/himdcli.c index 3b15678..20928f6 100644 --- a/himdcli/himdcli.c +++ b/himdcli/himdcli.c @@ -16,17 +16,20 @@ void usage(char * cmdname) { - printf("Usage: %s , where is either of:\n\n\ - strings - dumps all strings found in the tracklist file\n\ - tracks - lists all tracks on disc\n\ - tracks verbose - lists details of all tracks on disc\n\ - discid - reads the disc id of the inserted medium\n\ - holes - lists all holes on disc\n\ - mp3key - show the MP3 encryption key for track \n\ - dumptrack - dump track \n\ - dumpmp3 - dump MP3 track \n\ - dumpnonmp3 - dump non-MP3 track \n\ - writemp3 - write mp3 to disc\n", cmdname); + printf("Usage: %s , where is either of:\n\n" + " strings - dumps all strings found in the tracklist file\n" + " tracks - lists all tracks on disc\n" + " tracks verbose - lists details of all tracks on disc\n" + " discid - reads the disc id of the inserted medium\n" + " holes - lists all holes on disc\n" + " mp3key - show the MP3 encryption key for track \n" + " dumptrack - dump track \n" + " dumpmp3 - dump MP3 track \n" + " dumpnonmp3 - dump non-MP3 track \n" + " writemp3 - write mp3 to disc\n" + " settitle - Set <TRK>'s title to <TITLE>\n" + " setartist <TRK> <ARTIST> - Set <TRK>'s artist to <ARTIST>\n" + " setalbum <TRK> <ALBUM> - Set <TRK>'s album to <ALBUM>\n", cmdname); } static const char * hexdump(unsigned char * input, int len) @@ -723,6 +726,12 @@ void himd_writemp3(struct himd *h, const char *filepath) free(artist); free(album); free(title); } +void himd_relabel_track(struct himd * h, int idx, char * label, int label_type) +{ + himd_set_track_label(h, idx, label, label_type, NULL); + himd_write_tifdata(h, NULL); +} + int main(int argc, char ** argv) { int idx; @@ -783,6 +792,24 @@ int main(int argc, char ** argv) { himd_writemp3(&h, argv[3]); } + else if(strcmp(argv[2],"settitle") == 0 && argc > 4) + { + idx = 1; + sscanf(argv[3], "%d", &idx); + himd_relabel_track(&h, idx, argv[4], LABEL_TYPE_TITLE); + } + else if(strcmp(argv[2],"setartist") == 0 && argc > 4) + { + idx = 1; + sscanf(argv[3], "%d", &idx); + himd_relabel_track(&h, idx, argv[4], LABEL_TYPE_ARTIST); + } + else if(strcmp(argv[2],"setalbum") == 0 && argc > 4) + { + idx = 1; + sscanf(argv[3], "%d", &idx); + himd_relabel_track(&h, idx, argv[4], LABEL_TYPE_ALBUM); + } himd_close(&h); return 0; diff --git a/libhimd/himd.h b/libhimd/himd.h index 6a3aa16..df59bc8 100644 --- a/libhimd/himd.h +++ b/libhimd/himd.h @@ -179,6 +179,22 @@ int himd_get_free_trackindex(struct himd * himd); int himd_add_track_info(struct himd * himd, struct trackinfo * track, struct himderrinfo * status); int himd_add_fragment_info(struct himd * himd, struct fraginfo * f, struct himderrinfo * status); +struct himd_editable_trackinfo { + struct trackinfo data; + int index; +}; + +int himd_start_update_track_info(struct himd * himd, unsigned int idx, struct himd_editable_trackinfo * t, struct himderrinfo * status); +int himd_commit_update_track_info(struct himd * himd, struct himd_editable_trackinfo * t, struct himderrinfo * status); + +enum himd_label_type { + LABEL_TYPE_TITLE, + LABEL_TYPE_ARTIST, + LABEL_TYPE_ALBUM +}; + +int himd_set_track_label(struct himd * himd, int trackindex, const char * label, enum himd_label_type label_type, struct himderrinfo * status); + #define himd_get_codec_name(track) sony_codecinfo_codecname(&(track)->codec_info) #define himd_trackinfo_framesize(track) sony_codecinfo_bytesperframe(&(track)->codec_info) unsigned int himd_trackinfo_framesperblock(const struct trackinfo * track); diff --git a/libhimd/trackindex.c b/libhimd/trackindex.c index c8fe434..1ce735d 100644 --- a/libhimd/trackindex.c +++ b/libhimd/trackindex.c @@ -273,6 +273,38 @@ int himd_add_track_info(struct himd * himd, struct trackinfo * t, struct himderr } +int himd_start_update_track_info(struct himd * himd, unsigned int idx, struct himd_editable_trackinfo * t, struct himderrinfo * status) +{ + g_return_val_if_fail(himd != NULL, -1); + g_return_val_if_fail(t != NULL, -1); + + if(himd_get_track_info(himd, idx, &(t->data), status) < 0) + { + t->index = -1; + return -1; + } + + t->index = idx; + + return 0; +} + +int himd_commit_update_track_info(struct himd * himd, struct himd_editable_trackinfo * t, struct himderrinfo * status) +{ + unsigned char * trackbuffer; + + g_return_val_if_fail(himd != NULL, -1); + g_return_val_if_fail(t != NULL, -1); + g_return_val_if_fail(t->index >= 0, -1); + + trackbuffer = get_track(himd, t->index); + settrack(&(t->data), trackbuffer); + + (void)status; + return 0; +} + + unsigned int himd_trackinfo_framesperblock(const struct trackinfo * track) { int framesize; @@ -578,3 +610,126 @@ int himd_add_string(struct himd * himd, char *string, int type, struct himderrin return idx_firstslot; } + +int himd_delete_string(struct himd * himd, unsigned int idx, struct himderrinfo * status) +{ + unsigned char * cur_strchunk = NULL; + unsigned char * freelist_head = NULL; + unsigned int curidx, failed_at; + int type_of_head; + gboolean first = TRUE; + gboolean failed = FALSE; + + g_return_val_if_fail(idx != 0, -1); /* idx==0 is the head of the free list */ + + freelist_head = get_strchunk(himd, 0); + type_of_head = strtype(get_strchunk(himd, idx)); + + if((type_of_head == STRING_TYPE_CONTINUATION) || (type_of_head == STRING_TYPE_UNUSED)) + { + set_status_printf(status, HIMD_ERROR_NOT_STRING_HEAD, "String table entry %d is not a head: Type %d", curidx, type_of_head); + failed = TRUE; + } + + curidx = idx; + while((curidx > 0) && (!failed)) /* curidx == 0 --> End of string */ + { + cur_strchunk = get_strchunk(himd, curidx); + + if((!first) && (strtype(cur_strchunk) != STRING_TYPE_CONTINUATION)) + { + set_status_printf(status, HIMD_ERROR_STRING_CHAIN_BROKEN, "String slot %d has type %d, should be %d\n", curidx, strtype(cur_strchunk), STRING_TYPE_CONTINUATION); + failed = TRUE; + break; + } + + set_strtype(cur_strchunk, STRING_TYPE_UNUSED); /* Mark current chunk as unused */ + + curidx = strlink(cur_strchunk); + first = FALSE; + } + + if(failed) + { + /* Restore chain */ + failed_at = curidx; + + curidx = idx; + while(curidx != failed_at) + { + cur_strchunk = get_strchunk(himd, curidx); + set_strtype(cur_strchunk, STRING_TYPE_CONTINUATION); + + curidx = strlink(cur_strchunk); + } + + /* Restore type_of_head */ + cur_strchunk = get_strchunk(himd, idx); + set_strtype(cur_strchunk, type_of_head); + + return -1; + } + else + { + set_strlink(cur_strchunk, strlink(freelist_head)); /* cur_strchunk was the last chunk of our string */ + set_strlink(freelist_head, idx); + return 0; + } +} + +int himd_set_track_label(struct himd * himd, int trackindex, const char * label, enum himd_label_type label_type, struct himderrinfo * status) +{ + struct himd_editable_trackinfo t; + int string_idx; + int rv = 0; + int * string_dst; + int string_type; + + g_return_val_if_fail(himd != NULL, -1); + g_return_val_if_fail(label != NULL, -1); + + if(himd_start_update_track_info(himd, trackindex, &t, status) < 0) + return -1; + + g_return_val_if_fail((label_type == LABEL_TYPE_TITLE) || + (label_type == LABEL_TYPE_ARTIST) || + (label_type == LABEL_TYPE_ALBUM), -1); + + switch(label_type) + { + case LABEL_TYPE_TITLE: + string_dst = &(t.data.title); + string_type = STRING_TYPE_TITLE; + break; + case LABEL_TYPE_ARTIST: + string_dst = &(t.data.artist); + string_type = STRING_TYPE_ARTIST; + break; + case LABEL_TYPE_ALBUM: + string_dst = &(t.data.album); + string_type = STRING_TYPE_ALBUM; + break; + } + + if(*string_dst != 0) + { + if(himd_delete_string(himd, *string_dst, status) < 0) + return -1; + } + + *string_dst = 0; + + if(strcmp(label, "") != 0) + { + string_idx = himd_add_string(himd, label, string_type, status); + if(string_idx < 0) + rv = -1; /* An error occurred, but we should not just return -1 here, since *string_dst = 0 was not committed yet. */ + else + *string_dst = string_idx; + } + + if(himd_commit_update_track_info(himd, &t, status) < 0) + return -1; + + return rv; +} -- 1.8.0.2