[xiph-commits] r9600 - experimental/msmith
msmith at svn.xiph.org
msmith at svn.xiph.org
Fri Jul 22 10:17:17 PDT 2005
Author: msmith
Date: 2005-07-22 10:17:13 -0700 (Fri, 22 Jul 2005)
New Revision: 9600
Added:
experimental/msmith/README
experimental/msmith/fix-eos.c
experimental/msmith/fix-granulepos-on-empty-pages.c
experimental/msmith/make-ogg.c
experimental/msmith/ogg-pageinfo.c
experimental/msmith/remove-negative-granulepos.c
Log:
Add some tools I wrote for diagnosing, testing, and fixing various ogg
problems.
Added: experimental/msmith/README
===================================================================
--- experimental/msmith/README 2005-07-22 17:13:52 UTC (rev 9599)
+++ experimental/msmith/README 2005-07-22 17:17:13 UTC (rev 9600)
@@ -0,0 +1,5 @@
+These are some tools I wrote for diagnosing and fixing problems in ogg files.
+ogg-pageinfo is useful for figuring out what is actually on each ogg page.
+fix-* fix various problems, running them in the proper order is usually required
+play around if you want, there's no makefile, most of them require liboggz.
+
Added: experimental/msmith/fix-eos.c
===================================================================
--- experimental/msmith/fix-eos.c 2005-07-22 17:13:52 UTC (rev 9599)
+++ experimental/msmith/fix-eos.c 2005-07-22 17:17:13 UTC (rev 9600)
@@ -0,0 +1,198 @@
+/*
+ Copyright (C) 2003 Commonwealth Scientific and Industrial Research
+ Organisation (CSIRO) Australia
+ Also (C) 2005 Michael Smith <msmith at xiph.org>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ - Neither the name of CSIRO Australia nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <oggz/oggz.h>
+#include <ogg/ogg.h>
+
+struct eos_fix {
+ /* Output file */
+ FILE *out;
+
+ /* Stream serial -> struct eos_fix_stream mapping */
+ OggzTable * tracks;
+};
+
+/* We have one of these for each logical stream */
+struct eos_fix_stream {
+ long lastvalidpage; /* The pageno of the final useful page */
+ int discarding; /* Once we've processed the final useful page, we throw
+ out any further non-useful streams */
+};
+
+static void clear_table(OggzTable *table) {
+ int i, size = oggz_table_size(table);
+ for(i = 0; i < size; i++) {
+ free(oggz_table_nth(table, i, NULL));
+ }
+}
+
+static int
+read_page (OGGZ * oggz, const ogg_page * og, long serialno, void * user_data)
+{
+ struct eos_fix *fixer = (struct eos_fix *)user_data;
+ OggzTable * tracks = fixer->tracks;
+ long pageno = ogg_page_pageno((ogg_page *)og);
+
+ /* Insert this if it's a page that completes one or more packets; each time
+ * we call this it gets overwritten, the end result is that we mark the last
+ * page that contains the end of one or more packets.
+ */
+ if(ogg_page_packets((ogg_page *)og) != 0) {
+ struct eos_fix_stream *data = (struct eos_fix_stream *)oggz_table_lookup(tracks, serialno);
+ if(data == NULL) {
+ data = malloc(sizeof(struct eos_fix_stream));
+ }
+ data->lastvalidpage = pageno;
+ data->discarding = 0;
+ oggz_table_insert (tracks, serialno, data);
+ }
+
+ return 0;
+}
+
+static int
+write_page (OGGZ * oggz, const ogg_page * og, long serialno, void * user_data)
+{
+ struct eos_fix *fixer = (struct eos_fix *)user_data;
+ OggzTable * tracks = fixer->tracks;
+ long pageno = ogg_page_pageno((ogg_page *)og);
+ struct eos_fix_stream *data = (struct eos_fix_stream *)oggz_table_lookup(tracks, serialno);
+
+ if(data == NULL) {
+ fprintf(stderr, "Bailing out, internal consistency failure\n");
+ abort();
+ }
+
+ if(data->lastvalidpage == pageno) {
+ unsigned char header_type = og->header[5];
+ if(!(header_type & 0x4)) {
+ fprintf(stderr, "Setting EOS on final page of stream %ld\n",
+ serialno);
+ header_type |= 0x4;
+ og->header[5] = header_type;
+
+ ogg_page_checksum_set((ogg_page *)og);
+ }
+
+ /* Now we want to discard any remaining partial packets at the end of this
+ * page. Unfortunately, neither libogg nor liboggz have helpful
+ * functions for this, so do it all in a manual way...
+ *
+ * We need to do this because libogg (correctly) doesn't tag the last
+ * complete packet on an EOS page with EOS if there's an incomplete
+ * packet following it (so you get complaints from oggz-validate).
+ */
+ {
+ int i, segments, discard = 0;
+ segments = og->header[26];
+ for(i=segments-1; i >= 0; i--) {
+ if(og->header[i+27] < 255)
+ break;
+ else
+ discard += 255;
+ }
+ if(i != segments-1) {
+ fprintf(stderr, "Discarding %d useless segments of %d, retaining %d\n", segments-1-i, segments, i+1);
+ og->header[26] = i+1;
+ ((ogg_page *)og)->header_len -= segments-1-i;
+ ((ogg_page *)og)->body_len -= discard;
+ ogg_page_checksum_set((ogg_page *)og);
+ }
+ }
+
+ /* Write out this page, but no following ones */
+ fwrite (og->header, 1, og->header_len, fixer->out);
+ fwrite (og->body, 1, og->body_len, fixer->out);
+ data->discarding = 1;
+ }
+
+ if(!data->discarding) {
+ fwrite (og->header, 1, og->header_len, fixer->out);
+ fwrite (og->body, 1, og->body_len, fixer->out);
+ }
+
+ return 0;
+}
+
+int
+main (int argc, char ** argv)
+{
+ OGGZ * oggz;
+ struct eos_fix fixer;
+ long n;
+ char *progname = argv[0];
+
+ if (argc < 3) {
+ printf ("usage: %s in.ogg out.ogg\n", progname);
+ }
+
+ fixer.tracks = oggz_table_new ();
+ fixer.out = NULL;
+
+ if ((oggz = oggz_open ((char *)argv[1], OGGZ_READ | OGGZ_AUTO)) == NULL) {
+ printf ("%s: unable to open file %s\n", progname, argv[1]);
+ exit (1);
+ }
+
+ oggz_set_read_page (oggz, -1, read_page, &fixer);
+
+ while ((n = oggz_read (oggz, 1024)) > 0);
+
+ oggz_close (oggz);
+
+ fixer.out = fopen(argv[2], "wb");
+ if(!fixer.out) {
+ fprintf(stderr, "%s: Failed to open output file \"%s\"\n", progname, argv[2]);
+ exit(1);
+ }
+
+ if ((oggz = oggz_open ((char *)argv[1], OGGZ_READ | OGGZ_AUTO)) == NULL) {
+ printf ("%s: unable to open file %s\n", progname, argv[1]);
+ exit (1);
+ }
+
+ oggz_set_read_page (oggz, -1, write_page, &fixer);
+
+ while ((n = oggz_read (oggz, 1024)) > 0);
+
+ oggz_close (oggz);
+
+ clear_table(fixer.tracks);
+ oggz_table_delete (fixer.tracks);
+
+ fclose(fixer.out);
+
+ exit (0);
+}
Added: experimental/msmith/fix-granulepos-on-empty-pages.c
===================================================================
--- experimental/msmith/fix-granulepos-on-empty-pages.c 2005-07-22 17:13:52 UTC (rev 9599)
+++ experimental/msmith/fix-granulepos-on-empty-pages.c 2005-07-22 17:17:13 UTC (rev 9600)
@@ -0,0 +1,98 @@
+/*
+ Copyright (C) 2003 Commonwealth Scientific and Industrial Research
+ Organisation (CSIRO) Australia
+ Also (C) 2005 Michael Smith <msmith at xiph.org>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ - Neither the name of CSIRO Australia nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <oggz/oggz.h>
+#include <ogg/ogg.h>
+
+static FILE *out;
+
+static char * progname;
+
+static int
+process_page (OGGZ * oggz, const ogg_page * og, long serialno, void * user_data)
+{
+ ogg_int64_t gpos = ogg_page_granulepos((ogg_page *)og);
+
+ if(gpos != -1 && ogg_page_packets((ogg_page *)og) == 0) {
+ int i;
+
+ fprintf(stderr, "Fixing granulepos on page with no completed packets\n");
+ for(i=6;i<14;i++){
+ gpos = -1;
+ og->header[i]=(unsigned char)(gpos&0xff);
+ gpos>>=8;
+ }
+ ogg_page_checksum_set((ogg_page *)og);
+ }
+
+ fwrite (og->header, 1, og->header_len, out);
+ fwrite (og->body, 1, og->body_len, out);
+
+ return 0;
+}
+
+int
+main (int argc, char ** argv)
+{
+ OGGZ * oggz;
+ long n;
+
+ progname = argv[0];
+
+ if (argc < 3) {
+ printf ("usage: %s in.ogg out.ogg\n", progname);
+ }
+
+ if ((oggz = oggz_open ((char *)argv[1], OGGZ_READ | OGGZ_AUTO)) == NULL) {
+ printf ("%s: unable to open file %s\n", progname, argv[1]);
+ exit (1);
+ }
+
+ out = fopen(argv[2], "wb");
+ if(!out) {
+ fprintf(stderr, "%s: Failed to open output file \"%s\"\n", progname, argv[2]);
+ exit(1);
+ }
+
+ oggz_set_read_page (oggz, -1, process_page, NULL);
+
+ while ((n = oggz_read (oggz, 1024)) > 0);
+
+ oggz_close (oggz);
+
+ fclose(out);
+
+ exit (0);
+}
Added: experimental/msmith/make-ogg.c
===================================================================
--- experimental/msmith/make-ogg.c 2005-07-22 17:13:52 UTC (rev 9599)
+++ experimental/msmith/make-ogg.c 2005-07-22 17:17:13 UTC (rev 9600)
@@ -0,0 +1,68 @@
+#include <ogg/ogg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+void write_ogg(FILE *out)
+{
+ ogg_packet packet;
+ ogg_page page;
+ int sizes[] = {10, 100, 1000, 10000, -1};
+ int i = 0;
+ ogg_int64_t current_granulepos = 0;
+ ogg_stream_state stream;
+ int serial = 123456;
+
+ ogg_stream_init(&stream, serial);
+
+ while(sizes[i] >= 0) {
+ int size = sizes[i];
+ fprintf(stderr, "Doing size %d\n", size);
+
+ packet.b_o_s = (i == 0);
+ packet.e_o_s = sizes[i+1] < 0;
+ packet.packet = calloc(1, size);
+ packet.bytes = size;
+ packet.packetno = i;
+ packet.granulepos = current_granulepos;
+
+ current_granulepos += 1;
+
+ fprintf(stderr, "Submitting packet with GP %lld\n", packet.granulepos);
+ ogg_stream_packetin(&stream, &packet);
+
+ while(ogg_stream_pageout(&stream, &page))
+ {
+ fprintf(stderr, "Writing page %ld\n", ogg_page_pageno(&page));
+ fwrite(page.header, 1, page.header_len, out);
+ fwrite(page.body, 1, page.body_len, out);
+ }
+
+ i++;
+ }
+
+ ogg_stream_clear(&stream);
+}
+
+int main(int argc, char **argv)
+{
+ FILE *out;
+
+ if(argc < 2) {
+ fprintf(stderr, "Usage: make-ogg out.ogg\n");
+ exit(1);
+ }
+
+ out = fopen(argv[1], "wb");
+
+ if(!out) {
+ fprintf(stderr, "Couldn't write to %s\n", argv[1]);
+ exit(1);
+ }
+
+ write_ogg(out);
+ fclose(out);
+
+ return 0;
+}
+
+
Added: experimental/msmith/ogg-pageinfo.c
===================================================================
--- experimental/msmith/ogg-pageinfo.c 2005-07-22 17:13:52 UTC (rev 9599)
+++ experimental/msmith/ogg-pageinfo.c 2005-07-22 17:17:13 UTC (rev 9600)
@@ -0,0 +1,120 @@
+/*
+ Copyright (C) 2003 Commonwealth Scientific and Industrial Research
+ Organisation (CSIRO) Australia
+ Also (C) 2005 Michael Smith <msmith at xiph.org>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ - Neither the name of CSIRO Australia nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <oggz/oggz.h>
+#include <ogg/ogg.h>
+
+static int
+process_page (OGGZ * oggz, const ogg_page * og, long serialno, void * user_data)
+{
+ ogg_int64_t gpos = ogg_page_granulepos((ogg_page *)og);
+ int granuleshift = oggz_get_granuleshift(oggz, serialno);
+
+ fprintf (stdout, "|%010ld| ", serialno);
+ fprintf(stdout, "page %ld, ", ogg_page_pageno((ogg_page *)og));
+ if(granuleshift < 1) {
+ fprintf(stdout, "GP %lld, ", gpos);
+ }
+ else {
+ ogg_int64_t iframe, pframe;
+ iframe = gpos >> granuleshift;
+ pframe = gpos - (iframe << granuleshift);
+
+ fprintf (stdout, "granulepos %lld|%lld, ", iframe, pframe);
+ }
+
+ fprintf(stdout, "Flags: ");
+ if(ogg_page_continued((ogg_page *)og))
+ fprintf(stdout, "C");
+ if(ogg_page_bos((ogg_page *)og))
+ fprintf(stdout, "B");
+ if(ogg_page_eos((ogg_page *)og))
+ fprintf(stdout, "E");
+
+ fprintf(stdout, " (%d)", ogg_page_packets((ogg_page *)og));
+
+ fprintf(stdout, "\n");
+
+
+ return 0;
+}
+
+int process_packet(OGGZ *oggz, ogg_packet *op, long serialno, void *user_data)
+{
+ int granuleshift = oggz_get_granuleshift (oggz, serialno);
+ fprintf (stdout, "|%010ld| ", serialno);
+ if(granuleshift < 1) {
+ fprintf(stdout, "GP %lld, ", op->granulepos);
+ }
+ else {
+ ogg_int64_t iframe, pframe;
+ iframe = op->granulepos >> granuleshift;
+ pframe = op->granulepos - (iframe << granuleshift);
+
+ fprintf (stdout, "GP %lld|%lld, ", iframe, pframe);
+ }
+ fprintf (stdout, " packetno %lld", op->packetno);
+
+ fprintf(stdout, ": %ld bytes\n", op->bytes);
+
+ return 0;
+}
+
+int
+main (int argc, char ** argv)
+{
+ OGGZ * oggz;
+ long n;
+
+ char *progname = argv[0];
+
+ if (argc < 2) {
+ printf ("usage: %s file.ogg\n", progname);
+ }
+
+ if ((oggz = oggz_open ((char *)argv[1], OGGZ_READ | OGGZ_AUTO)) == NULL) {
+ printf ("%s: unable to open file %s\n", progname, argv[1]);
+ exit (1);
+ }
+
+ oggz_set_read_page (oggz, -1, process_page, NULL);
+ oggz_set_read_callback(oggz, -1, process_packet, NULL);
+
+ while ((n = oggz_read (oggz, 1024)) > 0);
+
+ oggz_close (oggz);
+
+ exit (0);
+}
Added: experimental/msmith/remove-negative-granulepos.c
===================================================================
--- experimental/msmith/remove-negative-granulepos.c 2005-07-22 17:13:52 UTC (rev 9599)
+++ experimental/msmith/remove-negative-granulepos.c 2005-07-22 17:17:13 UTC (rev 9600)
@@ -0,0 +1,106 @@
+/*
+ Copyright (C) 2003 Commonwealth Scientific and Industrial Research
+ Organisation (CSIRO) Australia
+ Also (C) 2005 Michael Smith <msmith at xiph.org>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ - Neither the name of CSIRO Australia nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <oggz/oggz.h>
+#include <ogg/ogg.h>
+
+static FILE *out;
+
+static char * progname;
+
+long pages_written = 0;
+
+static void set_ogg_pageno(ogg_page *og, long pageno) {
+ int i;
+ for(i=18;i<22;i++){
+ og->header[i]=(unsigned char)(pageno&0xff);
+ pageno>>=8;
+ }
+ ogg_page_checksum_set(og);
+}
+
+static int
+process_page (OGGZ * oggz, const ogg_page * og, long serialno, void * user_data)
+{
+ ogg_int64_t gpos = ogg_page_granulepos((ogg_page *)og);
+
+ if(gpos < -1) {
+ fprintf(stderr, "Skipping page with granulepos %lld\n", gpos);
+ }
+ else {
+ if(ogg_page_pageno((ogg_page *)og) != pages_written)
+ set_ogg_pageno((ogg_page *)og, pages_written);
+
+ fwrite (og->header, 1, og->header_len, out);
+ fwrite (og->body, 1, og->body_len, out);
+ pages_written++;
+ }
+
+ return 0;
+}
+
+int
+main (int argc, char ** argv)
+{
+ OGGZ * oggz;
+ long n;
+
+ progname = argv[0];
+
+ if (argc < 3) {
+ printf ("usage: %s in.ogg out.ogg\n", progname);
+ }
+
+ if ((oggz = oggz_open ((char *)argv[1], OGGZ_READ | OGGZ_AUTO)) == NULL) {
+ printf ("%s: unable to open file %s\n", progname, argv[1]);
+ exit (1);
+ }
+
+ out = fopen(argv[2], "wb");
+ if(!out) {
+ fprintf(stderr, "%s: Failed to open output file \"%s\"\n", progname, argv[2]);
+ exit(1);
+ }
+
+ oggz_set_read_page (oggz, -1, process_page, NULL);
+
+ while ((n = oggz_read (oggz, 1024)) > 0);
+
+ oggz_close (oggz);
+
+ fclose(out);
+
+ exit (0);
+}
More information about the commits
mailing list