parse tags

This commit is contained in:
Frédéric Mangano 2013-01-01 14:25:20 +01:00
parent 62a65af712
commit ee702d71e2

View File

@ -4,6 +4,61 @@
#include <string.h>
#include <ogg/ogg.h>
typedef struct {
uint32_t vendor_length;
const char *vendor_string;
uint32_t count;
uint32_t *lengths;
const char **comment;
} opus_tags;
int parse_tags(char *data, long len, opus_tags *tags){
long pos;
if(len < 8+4+4)
return -1;
if(strncmp(data, "OpusTags", 8) != 0)
return -1;
// Vendor
pos = 8;
tags->vendor_length = le32toh(*((uint32_t*) (data + pos)));
tags->vendor_string = data + pos + 4;
pos += 4 + tags->vendor_length;
if(pos + 4 > len)
return -1;
// Count
tags->count = le32toh(*((uint32_t*) (data + pos)));
if(tags->count == 0)
return 0;
tags->lengths = calloc(tags->count, sizeof(uint32_t));
if(tags->lengths == NULL)
return -1;
tags->comment = calloc(tags->count, sizeof(const char*));
if(tags->comment == NULL){
free(tags->lengths);
return -1;
}
pos += 4;
// Comment
uint32_t i;
for(i=0; i<tags->count; i++){
tags->lengths[i] = le32toh(*((uint32_t*) (data + pos)));
tags->comment[i] = data + pos + 4;
pos += 4 + tags->lengths[i];
if(pos > len)
return -1;
}
if(pos != len)
return -1;
return 0;
}
void free_tags(opus_tags *tags){
if(tags->count > 0){
free(tags->lengths);
free(tags->comment);
}
}
int main(int argc, char **argv){
FILE *in = fopen(argv[1], "r");
if(!in){
@ -14,6 +69,7 @@ int main(int argc, char **argv){
ogg_stream_state os;
ogg_page og;
ogg_packet op;
opus_tags tags;
ogg_sync_init(&oy);
char *buf;
size_t len;
@ -54,8 +110,16 @@ int main(int argc, char **argv){
error = "opustags: invalid identification header";
}
if(packet_count == 2){ // Comment header
if(strncmp((char*) op.packet, "OpusTags", 8) != 0)
if(parse_tags((char*) op.packet, op.bytes, &tags) == -1)
error = "opustags: invalid comment header";
fwrite(tags.vendor_string, 1, tags.vendor_length, stdout);
puts("");
int i;
for(i=0; i<tags.count; i++){
fwrite(tags.comment[i], 1, tags.lengths[i], stdout);
puts("");
}
free_tags(&tags);
break;
}
}