[xiph-cvs] cvs commit: vorbis-tools/vorbiscomment vcedit.c vcedit.h vcomment.c
Michael Smith
msmith at xiph.org
Fri Feb 9 22:26:23 PST 2001
msmith 01/02/09 22:26:22
Modified: vorbiscomment vcedit.c vcedit.h vcomment.c
Log:
Lots of changes to make writing frontends easier.
Bugfixes for chained streams.
Revision Changes Path
1.6 +79 -43 vorbis-tools/vorbiscomment/vcedit.c
Index: vcedit.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis-tools/vorbiscomment/vcedit.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- vcedit.c 2001/01/30 10:42:49 1.5
+++ vcedit.c 2001/02/10 06:26:22 1.6
@@ -6,12 +6,12 @@
*
* Comment editing backend, suitable for use by nice frontend interfaces.
*
- * last modified: $Id: vcedit.c,v 1.5 2001/01/30 10:42:49 msmith Exp $
+ * last modified: $Id: vcedit.c,v 1.6 2001/02/10 06:26:22 msmith Exp $
*/
-
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <ogg/ogg.h>
#include <vorbis/codec.h>
@@ -27,13 +27,11 @@
return state;
}
-void vcedit_clear(vcedit_state *state)
+char *vcedit_error(vcedit_state *state)
{
- if(state)
- free(state);
+ return state->lasterror;
}
-
vorbis_comment *vcedit_comments(vcedit_state *state)
{
return state->vc;
@@ -61,10 +59,25 @@
}
}
+void vcedit_clear(vcedit_state *state)
+{
+ if(state)
+ {
+ vcedit_clear_internals(state);
+ free(state);
+ }
+}
int vcedit_open(vcedit_state *state, FILE *in)
{
+ return vcedit_open_callbacks(state, (void *)in,
+ (vcedit_read_func)fread, (vcedit_write_func)fwrite);
+}
+int vcedit_open_callbacks(vcedit_state *state, void *in,
+ vcedit_read_func read_func, vcedit_write_func write_func)
+{
+
char *buffer;
int bytes,i;
ogg_packet *header;
@@ -76,21 +89,23 @@
state->in = in;
+ state->read = read_func;
+ state->write = write_func;
state->oy = malloc(sizeof(ogg_sync_state));
ogg_sync_init(state->oy);
buffer = ogg_sync_buffer(state->oy, CHUNKSIZE);
- bytes = fread(buffer, 1, CHUNKSIZE, state->in);
+ bytes = state->read(buffer, 1, CHUNKSIZE, state->in);
ogg_sync_wrote(state->oy, bytes);
if(ogg_sync_pageout(state->oy, &og) != 1)
{
if(bytes<CHUNKSIZE)
- fprintf(stderr, "Input truncated or empty.\n");
+ state->lasterror = "Input truncated or empty.";
else
- fprintf(stderr, "Input does not appear to be an Ogg bitstream.\n");
+ state->lasterror = "Input is not an Ogg bitstream.";
goto err;
}
@@ -106,19 +121,19 @@
if(ogg_stream_pagein(state->os, &og) < 0)
{
- fprintf(stderr, "Error reading first page of Ogg bitstream.\n");
+ state->lasterror = "Error reading first page of Ogg bitstream.";
goto err;
}
if(ogg_stream_packetout(state->os, &header_main) != 1)
{
- fprintf(stderr, "Error reading initial header packet.\n");
+ state->lasterror = "Error reading initial header packet.";
goto err;
}
if(vorbis_synthesis_headerin(&vi, state->vc, &header_main) < 0)
{
- fprintf(stderr, "Ogg bitstream does not contain vorbis data.\n");
+ state->lasterror = "Ogg bitstream does not contain vorbis data.";
goto err;
}
@@ -141,7 +156,7 @@
if(result == 0) break;
if(result == -1)
{
- fprintf(stderr, "Corrupt secondary header.\n");
+ state->lasterror = "Corrupt secondary header.";
goto err;
}
vorbis_synthesis_headerin(&vi, state->vc, header);
@@ -159,10 +174,10 @@
}
buffer = ogg_sync_buffer(state->oy, CHUNKSIZE);
- bytes = fread(buffer, 1, CHUNKSIZE, state->in);
+ bytes = state->read(buffer, 1, CHUNKSIZE, state->in);
if(bytes == 0 && i < 2)
{
- fprintf(stderr, "EOF before end of vorbis headers.\n");
+ state->lasterror = "EOF before end of vorbis headers.";
goto err;
}
ogg_sync_wrote(state->oy, bytes);
@@ -177,7 +192,7 @@
return -1;
}
-int vcedit_write(vcedit_state *state, FILE *out)
+int vcedit_write(vcedit_state *state, void *out)
{
ogg_stream_state streamout;
ogg_packet header_main;
@@ -212,20 +227,20 @@
while((result = ogg_stream_flush(&streamout, &ogout)))
{
- if(fwrite(ogout.header,1,ogout.header_len, out) != ogout.header_len)
+ if(state->write(ogout.header,1,ogout.header_len, out) != ogout.header_len)
goto cleanup;
- if(fwrite(ogout.body,1,ogout.body_len, out) != ogout.body_len)
+ if(state->write(ogout.body,1,ogout.body_len, out) != ogout.body_len)
goto cleanup;
}
- while(!(eosin && eosout))
+ while(!eosout)
{
- while(!(eosin && !eosout))
+ while(!eosout)
{
result = ogg_sync_pageout(state->oy, &ogin);
if(result==0) break; /* Need more data... */
else if(result ==-1)
- fprintf(stderr, "Recoverable error in bitstream\n");
+ continue;
else
{
ogg_stream_pagein(state->os, &ogin);
@@ -234,50 +249,71 @@
{
result = ogg_stream_packetout(state->os, &op);
if(result==0)break;
- else if(result==-1)
- fprintf(stderr, "Recoverable error in bitstream\n");
+ else if(result==-1)
+ continue;
else
{
ogg_stream_packetin(&streamout, &op);
- while(!(eosin && eosout))
+ while(!eosout)
{
- int result = ogg_stream_pageout(&streamout, &ogout);
+ int result=ogg_stream_pageout(&streamout, &ogout);
if(result==0)break;
- if(fwrite(ogout.header,1,ogout.header_len, out) !=
- ogout.header_len)
+ if(state->write(ogout.header,1,ogout.header_len,
+ out) != ogout.header_len)
goto cleanup;
- if(fwrite(ogout.body,1,ogout.body_len, out) !=
- ogout.body_len)
+ if(state->write(ogout.body,1,ogout.body_len,
+ out) != ogout.body_len)
goto cleanup;
- if(ogg_page_eos(&ogout)) eosout = 1;
+ if(ogg_page_eos(&ogout)) eosout=1;
}
}
}
if(ogg_page_eos(&ogin)) eosin = 1;
}
}
- if(!(eosin && eosout))
+ if(!eosin)
{
buffer = ogg_sync_buffer(state->oy, CHUNKSIZE);
- bytes = fread(buffer,1, CHUNKSIZE, state->in);
+ bytes = state->read(buffer,1, CHUNKSIZE, state->in);
ogg_sync_wrote(state->oy, bytes);
- if(bytes == 0) eosin = 1;
+ if(bytes == 0)
+ {
+ eosin = 1;
+ break;
+ }
}
}
- if(!feof(state->in)) /* We reached eos, not eof */
+ while(!eosin) /* We reached eos, not eof */
{
- /* We copy the rest of the stream (other logical
- * streams) untouched. */
- bytes = 1;
- while(bytes)
+ /* We copy the rest of the stream (other logical streams)
+ * through, a page at a time. */
+ while(1)
{
- bytes = fread(buffer, 1, CHUNKSIZE, state->in);
- fwrite(buffer, 1, bytes, out);
+ result = ogg_sync_pageout(state->oy, &ogin);
+ if(result==0) break;
+ if(result<0)
+ state->lasterror = "Corrupt or missing data, continuing...";
+ else
+ {
+ /* Don't bother going through the rest, we can just
+ * write the page out now */
+ if(state->write(ogout.header,1,ogout.header_len,
+ out) != ogout.header_len)
+ goto cleanup;
+ if(state->write(ogout.body,1,ogout.body_len, out) !=
+ ogout.body_len)
+ goto cleanup;
+ }
}
+ buffer = ogg_sync_buffer(state->oy, CHUNKSIZE);
+ bytes = state->read(buffer,1, CHUNKSIZE, state->in);
+ ogg_sync_wrote(state->oy, bytes);
+ if(bytes == 0) eosin = 1;
+ break;
}
@@ -291,11 +327,11 @@
vcedit_clear_internals(state);
if(!(eosin && eosout))
{
- fprintf(stderr, "Error writing stream to output.\n"
- "Output stream may be corrupted or truncated.\n");
+ state->lasterror = "Error writing stream to output.\n"
+ "Output stream may be corrupted or truncated.";
return -1;
}
return 0;
}
-
+
1.4 +21 -5 vorbis-tools/vorbiscomment/vcedit.h
Index: vcedit.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis-tools/vorbiscomment/vcedit.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- vcedit.h 2001/01/22 11:44:05 1.3
+++ vcedit.h 2001/02/10 06:26:22 1.4
@@ -11,31 +11,47 @@
#ifndef __VCEDIT_H
#define __VCEDIT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
#include <ogg/ogg.h>
#include <vorbis/codec.h>
+typedef size_t (*vcedit_read_func)(void *, size_t, size_t, void *);
+typedef size_t (*vcedit_write_func)(const void *, size_t, size_t, void *);
+
typedef struct {
ogg_sync_state *oy;
ogg_stream_state *os;
vorbis_comment *vc;
+
+ vcedit_read_func read;
+ vcedit_write_func write;
- FILE *in;
+ void *in;
long serial;
unsigned char *mainbuf;
unsigned char *bookbuf;
int mainlen;
int booklen;
+ char *lasterror;
} vcedit_state;
extern vcedit_state * vcedit_new_state(void);
extern void vcedit_clear(vcedit_state *state);
extern vorbis_comment * vcedit_comments(vcedit_state *state);
extern int vcedit_open(vcedit_state *state, FILE *in);
-extern int vcedit_write(vcedit_state *state, FILE *out);
+extern int vcedit_open_callbacks(vcedit_state *state, void *in,
+ vcedit_read_func read_func, vcedit_write_func write_func);
+extern int vcedit_write(vcedit_state *state, void *out);
+extern char * vcedit_error(vcedit_state *state);
+
+#ifdef __cplusplus
+}
+#endif
-
-
#endif /* __VCEDIT_H */
-
1.6 +6 -3 vorbis-tools/vorbiscomment/vcomment.c
Index: vcomment.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis-tools/vorbiscomment/vcomment.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- vcomment.c 2001/01/23 10:39:29 1.5
+++ vcomment.c 2001/02/10 06:26:22 1.6
@@ -83,7 +83,8 @@
if(vcedit_open(state, param->in) < 0)
{
- fprintf(stderr, "Failed to open file as vorbis.\n");
+ fprintf(stderr, "Failed to open file as vorbis: %s\n",
+ vcedit_error(state));
return 1;
}
@@ -104,7 +105,8 @@
if(vcedit_open(state, param->in) < 0)
{
- fprintf(stderr, "Failed to open file as vorbis.\n");
+ fprintf(stderr, "Failed to open file as vorbis: %s\n",
+ vcedit_error(state));
return 1;
}
@@ -131,7 +133,8 @@
/* write out the modified stream */
if(vcedit_write(state, param->out) < 0)
{
- fprintf(stderr, "Failed to write comments to output file\n");
+ fprintf(stderr, "Failed to write comments to output file: %s\n",
+ vcedit_error(state));
return 1;
}
--- >8 ----
List archives: http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body. No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.
More information about the commits
mailing list