X-Git-Url: http://git.code-monkey.de/?a=blobdiff_plain;f=ext%2Fvcedit.c;h=10746706f71c97fbd0c620b4ca2d95f4d8d8be9b;hb=bf1f7624bee5a466b402825083190d3afbd9c28b;hp=b6c7dfd8d0d0db18e361b0fd79b37fa74a1664cb;hpb=fcd91ff1a3cc4a4f889abfd2af89119cbe262ad1;p=ruby-vorbistagger.git diff --git a/ext/vcedit.c b/ext/vcedit.c index b6c7dfd..1074670 100644 --- a/ext/vcedit.c +++ b/ext/vcedit.c @@ -17,6 +17,7 @@ */ #include +#include #include #include #include @@ -30,8 +31,6 @@ #define CHUNKSIZE 4096 -static int vcedit_open (vcedit_state *state); - struct vcedit_state_St { int refcount; @@ -56,6 +55,49 @@ struct vcedit_state_St { int eosin; }; +static void +vcedit_state_free (vcedit_state *state) +{ + free (state->oy); + free (state->os); + free (state->vc); + free (state->vi); + free (state->mainbuf); + free (state->bookbuf); + free (state->vendor); + + if (state->in) { + fclose (state->in); + state->in = NULL; + } + + free (state); +} + +static bool +vcedit_state_init (vcedit_state *state) +{ + state->refcount = 1; + + state->oy = malloc (sizeof (ogg_sync_state)); + if (!state->oy) + return false; + + state->os = malloc (sizeof (ogg_stream_state)); + if (!state->os) + return false; + + state->vc = malloc (sizeof (vorbis_comment)); + if (!state->vc) + return false; + + state->vi = malloc (sizeof (vorbis_info)); + if (!state->vi) + return false; + + return true; +} + vcedit_state * vcedit_state_new (const char *filename) { @@ -67,18 +109,14 @@ vcedit_state_new (const char *filename) memset (state, 0, sizeof (vcedit_state)); - state->refcount = 1; + if (!vcedit_state_init (state)) { + vcedit_state_free (state); + return NULL; + } snprintf (state->filename, sizeof (state->filename), "%s", filename); - state->in = fopen (state->filename, "rb"); - - if (vcedit_open (state) < 0) { - free (state); - return NULL; - } - return state; } @@ -97,23 +135,11 @@ vcedit_comments (vcedit_state *state) static void vcedit_clear_internals (vcedit_state *state) { - if (state->vc) { - vorbis_comment_clear (state->vc); - free (state->vc); - state->vc = NULL; - } - - if (state->os) { - ogg_stream_clear (state->os); - free (state->os); - state->os = NULL; - } + ogg_stream_clear (state->os); + ogg_sync_clear (state->oy); - if (state->oy) { - ogg_sync_clear (state->oy); - free (state->oy); - state->oy = NULL; - } + vorbis_info_clear (state->vi); + vorbis_comment_clear (state->vc); free (state->vendor); state->vendor = NULL; @@ -126,14 +152,7 @@ vcedit_clear_internals (vcedit_state *state) state->bookbuf = NULL; state->booklen = 0; - if (state->vi) { - vorbis_info_clear (state->vi); - free (state->vi); - state->vi = NULL; - } - state->serial = 0; - state->prevW = state->extrapage = state->eosin = 0; } void @@ -145,13 +164,11 @@ vcedit_state_ref (vcedit_state *state) void vcedit_state_unref (vcedit_state *state) { - state->refcount--; + if (--state->refcount) + return; - if (!state->refcount) { - fclose (state->in); - vcedit_clear_internals (state); - free (state); - } + vcedit_clear_internals (state); + vcedit_state_free (state); } /* Next two functions pulled straight from libvorbis, apart from one change @@ -168,6 +185,8 @@ _v_writestring (oggpack_buffer *o, char *s, int len) static int _commentheader_out (vorbis_comment *vc, char *vendor, ogg_packet *op) { + int i; + oggpack_buffer opb; oggpack_writeinit (&opb); @@ -183,16 +202,13 @@ _commentheader_out (vorbis_comment *vc, char *vendor, ogg_packet *op) /* comments */ oggpack_write (&opb, vc->comments, 32); - if (vc->comments) { - int i; - - for (i = 0; i < vc->comments; i++) { - if (vc->user_comments[i]) { - oggpack_write (&opb, vc->comment_lengths[i], 32); - _v_writestring (&opb, vc->user_comments[i], - vc->comment_lengths[i]); - } else - oggpack_write (&opb, 0, 32); + for (i = 0; i < vc->comments; i++) { + if (!vc->user_comments[i]) + oggpack_write (&opb, 0, 32); + else { + oggpack_write (&opb, vc->comment_lengths[i], 32); + _v_writestring (&opb, vc->user_comments[i], + vc->comment_lengths[i]); } } @@ -214,13 +230,12 @@ _commentheader_out (vorbis_comment *vc, char *vendor, ogg_packet *op) static int _blocksize (vcedit_state *s, ogg_packet *p) { - int this = vorbis_packet_blocksize (s->vi, p); - int ret = (this + s->prevW) / 4; + int this, ret = 0; - if (!s->prevW) { - s->prevW = this; - return 0; - } + this = vorbis_packet_blocksize (s->vi, p); + + if (s->prevW) + ret = (this + s->prevW) / 4; s->prevW = this; @@ -263,7 +278,7 @@ _fetch_next_packet (vcedit_state *s, ogg_packet *p, ogg_page *page) return _fetch_next_packet (s, p, page); } -static int +int vcedit_open (vcedit_state *state) { char *buffer; @@ -273,7 +288,12 @@ vcedit_open (vcedit_state *state) ogg_packet header_main, header_comments, header_codebooks; ogg_page og; - state->oy = malloc (sizeof (ogg_sync_state)); + state->in = fopen (state->filename, "rb"); + if (!state->in) { + state->lasterror = "Cannot open file."; + return -1; + } + ogg_sync_init (state->oy); while (1) { @@ -298,13 +318,8 @@ vcedit_open (vcedit_state *state) state->serial = ogg_page_serialno (&og); - state->os = malloc (sizeof (ogg_stream_state)); ogg_stream_init (state->os, state->serial); - - state->vi = malloc (sizeof (vorbis_info)); vorbis_info_init (state->vi); - - state->vc = malloc (sizeof (vorbis_comment)); vorbis_comment_init (state->vc); if (ogg_stream_pagein (state->os, &og) < 0) { @@ -418,8 +433,7 @@ vcedit_write (vcedit_state *state) return -1; } - state->eosin = 0; - state->extrapage = 0; + state->prevW = state->extrapage = state->eosin = 0; header_main.bytes = state->mainlen; header_main.packet = state->mainbuf; @@ -586,8 +600,6 @@ cleanup: } vcedit_clear_internals (state); - - state->in = fopen (state->filename, "rb"); vcedit_open (state); return 0;