Răsfoiți Sursa

Add comment support to stb_vorbis

Audino 6 ani în urmă
părinte
comite
2a0cff1288
1 a modificat fișierele cu 77 adăugiri și 1 ștergeri
  1. 77 1
      stb_vorbis.c

+ 77 - 1
stb_vorbis.c

@@ -130,9 +130,20 @@ typedef struct
    int max_frame_size;
 } stb_vorbis_info;
 
+typedef struct
+{
+   char *vendor;
+
+   int comment_list_length;
+   char **comment_list;
+} stb_vorbis_comment;
+
 // get general information about the file
 extern stb_vorbis_info stb_vorbis_get_info(stb_vorbis *f);
 
+// get ogg comments
+extern stb_vorbis_comment stb_vorbis_get_comment(stb_vorbis *f);
+
 // get the last error detected (clears it, too)
 extern int stb_vorbis_get_error(stb_vorbis *f);
 
@@ -759,6 +770,10 @@ struct stb_vorbis
    unsigned int temp_memory_required;
    unsigned int setup_temp_memory_required;
 
+   char *vendor;
+   int comment_list_length;
+   char **comment_list;
+
   // input config
 #ifndef STB_VORBIS_NO_STDIO
    FILE *f;
@@ -1539,6 +1554,16 @@ static int get8_packet(vorb *f)
    return x;
 }
 
+static int get32_packet(vorb *f)
+{
+   uint32 x;
+   x = get8_packet(f);
+   x += get8_packet(f) << 8;
+   x += get8_packet(f) << 16;
+   x += (uint32) get8_packet(f) << 24;
+   return x;
+}
+
 static void flush_packet(vorb *f)
 {
    while (get8_packet_raw(f) != EOP);
@@ -3631,8 +3656,43 @@ static int start_decoder(vorb *f)
 
    // second packet!
    if (!start_page(f))                              return FALSE;
-
+   
    if (!start_packet(f))                            return FALSE;
+
+   if (!next_segment(f))                            return FALSE;
+
+   if (get8_packet(f) != VORBIS_packet_comment)            return error(f, VORBIS_invalid_setup);
+   for (i=0; i < 6; ++i) header[i] = get8_packet(f);
+   if (!vorbis_validate(header))                    return error(f, VORBIS_invalid_setup);
+   //file vendor
+   len = get32_packet(f);
+   f->vendor = (char*)setup_malloc(f, sizeof(char) * (len+1));
+   for(i=0; i < len; ++i) {
+      f->vendor[i] = get8_packet(f);
+   }
+   f->vendor[len] = (char)NULL;
+   //user comments
+   f->comment_list_length = get32_packet(f);
+   f->comment_list = (char**)setup_malloc(f, sizeof(char*) * (f->comment_list_length));
+   
+   for(i=0; i < f->comment_list_length; ++i) {
+      len = get32_packet(f);
+      f->comment_list[i] = (char*)setup_malloc(f, sizeof(char) * (len+1));
+
+      for(j=0; j < len; ++j) {
+         f->comment_list[i][j] = get8_packet(f);
+      }
+      f->comment_list[i][len] = (char)NULL;
+   }
+
+   // framing_flag
+   x = get8_packet(f);
+   if (!(x & 1))                                    return error(f, VORBIS_invalid_setup);
+
+   
+   skip(f, f->bytes_in_seg);
+   f->bytes_in_seg = 0;
+
    do {
       len = next_segment(f);
       skip(f, len);
@@ -4149,6 +4209,13 @@ static int start_decoder(vorb *f)
 static void vorbis_deinit(stb_vorbis *p)
 {
    int i,j;
+
+   setup_free(p, p->vendor);
+   for (i=0; i < p->comment_list_length; ++i) {
+      setup_free(p, p->comment_list[i]);
+   }
+   setup_free(p, p->comment_list);
+
    if (p->residue_config) {
       for (i=0; i < p->residue_count; ++i) {
          Residue *r = p->residue_config+i;
@@ -4248,6 +4315,15 @@ stb_vorbis_info stb_vorbis_get_info(stb_vorbis *f)
    return d;
 }
 
+stb_vorbis_comment stb_vorbis_get_comment(stb_vorbis *f)
+{
+   stb_vorbis_comment d;
+   d.vendor = f->vendor;
+   d.comment_list_length = f->comment_list_length;
+   d.comment_list = f->comment_list;
+   return d;
+}
+
 int stb_vorbis_get_error(stb_vorbis *f)
 {
    int e = f->error;