[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