*/
#include <stdio.h>
+#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
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)
{
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);
+ vcedit_state_free (state);
return NULL;
}
static void
vcedit_clear_internals (vcedit_state *state)
{
- if (state->vc) {
- vorbis_comment_clear (state->vc);
- free (state->vc);
- state->vc = NULL;
- }
+ ogg_stream_clear (state->os);
+ ogg_sync_clear (state->oy);
- if (state->os) {
- ogg_stream_clear (state->os);
- free (state->os);
- state->os = NULL;
- }
-
- 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;
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
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
static int
_commentheader_out (vorbis_comment *vc, char *vendor, ogg_packet *op)
{
+ int i;
+
oggpack_buffer opb;
oggpack_writeinit (&opb);
/* 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]);
}
}
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;
ogg_packet header_main, header_comments, header_codebooks;
ogg_page og;
- state->oy = malloc (sizeof (ogg_sync_state));
ogg_sync_init (state->oy);
while (1) {
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) {
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;