static void mp3_parse_id3(struct mp3_data *data, size_t tagsize, struct tag **mpd_tag, struct replay_gain_info **replay_gain_info_r) { struct id3_tag *id3_tag = NULL; id3_length_t count; id3_byte_t const *id3_data; id3_byte_t *allocated = NULL; count = data->stream.bufend - data->stream.this_frame; if (tagsize <= count) { id3_data = data->stream.this_frame; mad_stream_skip(&(data->stream), tagsize); } else { allocated = g_malloc(tagsize); memcpy(allocated, data->stream.this_frame, count); mad_stream_skip(&(data->stream), count); while (count < tagsize) { size_t len; len = decoder_read(data->decoder, data->input_stream, allocated + count, tagsize - count); if (len == 0) break; else count += len; } if (count != tagsize) { g_debug("error parsing ID3 tag"); g_free(allocated); return; } id3_data = allocated; } id3_tag = id3_tag_parse(id3_data, tagsize); if (id3_tag == NULL) { g_free(allocated); return; } if (mpd_tag) { struct tag *tmp_tag = tag_id3_import(id3_tag); if (tmp_tag != NULL) { if (*mpd_tag != NULL) tag_free(*mpd_tag); *mpd_tag = tmp_tag; } } if (replay_gain_info_r) { struct replay_gain_info *tmp_rgi = parse_id3_replay_gain_info(id3_tag); if (tmp_rgi != NULL) { if (*replay_gain_info_r) replay_gain_info_free(*replay_gain_info_r); *replay_gain_info_r = tmp_rgi; } } id3_tag_delete(id3_tag); g_free(allocated); }
static void mp3_parse_id3(struct mp3_data *data, size_t tagsize, struct tag **mpd_tag) { #ifdef HAVE_ID3TAG struct id3_tag *id3_tag = NULL; id3_length_t count; id3_byte_t const *id3_data; id3_byte_t *allocated = NULL; count = data->stream.bufend - data->stream.this_frame; if (tagsize <= count) { id3_data = data->stream.this_frame; mad_stream_skip(&(data->stream), tagsize); } else { allocated = g_malloc(tagsize); memcpy(allocated, data->stream.this_frame, count); mad_stream_skip(&(data->stream), count); while (count < tagsize) { size_t len; len = decoder_read(data->decoder, data->input_stream, allocated + count, tagsize - count); if (len == 0) break; else count += len; } if (count != tagsize) { g_debug("error parsing ID3 tag"); g_free(allocated); return; } id3_data = allocated; } id3_tag = id3_tag_parse(id3_data, tagsize); if (id3_tag == NULL) { g_free(allocated); return; } if (mpd_tag) { struct tag *tmp_tag = tag_id3_import(id3_tag); if (tmp_tag != NULL) { if (*mpd_tag != NULL) tag_free(*mpd_tag); *mpd_tag = tmp_tag; } } if (data->decoder != NULL) { struct replay_gain_info rgi; char *mixramp_start; char *mixramp_end; float replay_gain_db = 0; if (parse_id3_replay_gain_info(&rgi, id3_tag)) { replay_gain_db = decoder_replay_gain(data->decoder, &rgi); data->found_replay_gain = true; } if (parse_id3_mixramp(&mixramp_start, &mixramp_end, id3_tag)) { g_debug("setting mixramp_tags"); decoder_mixramp(data->decoder, replay_gain_db, mixramp_start, mixramp_end); } } id3_tag_delete(id3_tag); g_free(allocated); #else /* !HAVE_ID3TAG */ (void)mpd_tag; /* This code is enabled when libid3tag is disabled. Instead of parsing the ID3 frame, it just skips it. */ size_t count = data->stream.bufend - data->stream.this_frame; if (tagsize <= count) { mad_stream_skip(&data->stream, tagsize); } else { mad_stream_skip(&data->stream, count); while (count < tagsize) { size_t len = tagsize - count; char ignored[1024]; if (len > sizeof(ignored)) len = sizeof(ignored); len = decoder_read(data->decoder, data->input_stream, ignored, len); if (len == 0) break; else count += len; } } #endif }