X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=opus_afh.c;h=ace83008d60db987cfa3350a13d5dc40d365819f;hp=b079bcd5f3f373ed3b9e4826f010edd0e70a6201;hb=741c19c2a25c5d9e165cb99f7ff512209b7bade6;hpb=7007aedb78262af262e7e7db8d010c6498e79290 diff --git a/opus_afh.c b/opus_afh.c index b079bcd5..ace83008 100644 --- a/opus_afh.c +++ b/opus_afh.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012-2013 Andre Noll + * Copyright (C) 2012 Andre Noll * * Licensed under the GPL v2. For licencing details see COPYING. */ @@ -19,6 +19,8 @@ static const char* opus_suffixes[] = {"opus", NULL}; +#define OPUS_COMMENT_HEADER "OpusTags" + static bool copy_if_tag_type(const char *tag, int taglen, const char *type, char **p) { @@ -40,7 +42,7 @@ static int opus_get_comments(char *comments, int length, /* min size of a opus header is 16 bytes */ if (length < 16) return -E_OPUS_COMMENT; - if (memcmp(p, "OpusTags", 8) != 0) + if (memcmp(p, OPUS_COMMENT_HEADER, strlen(OPUS_COMMENT_HEADER)) != 0) return -E_OPUS_COMMENT; p += 8; val = read_u32(p); @@ -133,6 +135,97 @@ static int opus_get_file_info(char *map, size_t numbytes, __a_unused int fd, return 1; } +static size_t opus_make_meta_packet(struct taginfo *tags, char **result) +{ + size_t sz; + char *buf, *p; + size_t comment_len = strlen(tags->comment), + artist_len = strlen(tags->artist), + title_len = strlen(tags->title), + album_len = strlen(tags->album), + year_len = strlen(tags->year); + uint32_t comment_sz = comment_len, + artist_sz = artist_len + strlen("artist="), + title_sz = title_len + strlen("title="), + album_sz = album_len + strlen("album="), + year_sz = year_len + strlen("year="); + uint32_t num_tags; + + sz = strlen(OPUS_COMMENT_HEADER) + + 4 /* comment length (always present) */ + + comment_sz + + 4; /* number of tags */ + num_tags = 0; + if (artist_len) { + num_tags++; + sz += 4 + artist_sz; + } + if (title_len) { + num_tags++; + sz += 4 + title_sz; + } + if (album_len) { + num_tags++; + sz += 4 + album_sz; + } + if (year_len) { + num_tags++; + sz += 4 + year_sz; + } + PARA_DEBUG_LOG("meta packet size: %zu bytes\n", sz); + /* terminating zero byte for the last sprintf() */ + buf = p = para_malloc(sz + 1); + memcpy(p, OPUS_COMMENT_HEADER, strlen(OPUS_COMMENT_HEADER)); + p += strlen(OPUS_COMMENT_HEADER); + write_u32(p, comment_sz); + p += 4; + strcpy(p, tags->comment); + p += comment_sz; + write_u32(p, num_tags); + p += 4; + if (artist_len) { + write_u32(p, artist_sz); + p += 4; + sprintf(p, "artist=%s", tags->artist); + p += artist_sz; + } + if (title_len) { + write_u32(p, title_sz); + p += 4; + sprintf(p, "title=%s", tags->title); + p += title_sz; + } + if (album_len) { + write_u32(p, album_sz); + p += 4; + sprintf(p, "album=%s", tags->album); + p += album_sz; + } + if (year_len) { + write_u32(p, year_sz); + p += 4; + sprintf(p, "year=%s", tags->year); + p += year_sz; + } + assert(p == buf + sz); + *result = buf; + return sz; +} + +static int opus_rewrite_tags(const char *map, size_t mapsize, + struct taginfo *tags, int output_fd, + __a_unused const char *filename) +{ + char *meta_packet; + size_t meta_sz; + int ret; + + meta_sz = opus_make_meta_packet(tags, &meta_packet); + ret = ogg_rewrite_tags(map, mapsize, output_fd, meta_packet, meta_sz); + free(meta_packet); + return ret; +} + /** * The init function of the ogg/opus audio format handler. * @@ -142,4 +235,5 @@ void opus_afh_init(struct audio_format_handler *afh) { afh->get_file_info = opus_get_file_info, afh->suffixes = opus_suffixes; + afh->rewrite_tags = opus_rewrite_tags; }