[xiph-commits] r15722 - experimental/giles/rogg

giles at svn.xiph.org giles at svn.xiph.org
Thu Feb 26 11:51:15 PST 2009


Author: giles
Date: 2009-02-26 11:51:14 -0800 (Thu, 26 Feb 2009)
New Revision: 15722

Added:
   experimental/giles/rogg/rogg_serial.c
Modified:
   experimental/giles/rogg/Makefile
   experimental/giles/rogg/README
Log:
Add rogg_serial script to rewrite the serial number field of an Ogg 
logical bitstream. Contributed by manx.


Modified: experimental/giles/rogg/Makefile
===================================================================
--- experimental/giles/rogg/Makefile	2009-02-25 03:19:38 UTC (rev 15721)
+++ experimental/giles/rogg/Makefile	2009-02-26 19:51:14 UTC (rev 15722)
@@ -8,7 +8,7 @@
 OPTS = -g -O2 -Wall
 
 rogg_UTILS = rogg_pagedump rogg_eosfix rogg_crcfix \
-	rogg_aspect rogg_stats
+	rogg_aspect rogg_stats rogg_serial
 
 all : librogg.a $(rogg_UTILS)
 
@@ -33,6 +33,9 @@
 rogg_stats : rogg_stats.o librogg.a
 	$(CC) $(CFLAGS) -o $@ $^
 
+rogg_serial : rogg_serial.o librogg.a
+	$(CC) $(CFLAGS) -o $@ $^
+
 check : all
 
 clean :

Modified: experimental/giles/rogg/README
===================================================================
--- experimental/giles/rogg/README	2009-02-25 03:19:38 UTC (rev 15721)
+++ experimental/giles/rogg/README	2009-02-26 19:51:14 UTC (rev 15722)
@@ -14,6 +14,12 @@
   of a stream. This is often unset in downloads truncated from
   an icecast stream.
 
+  rogg_crcfix will reset the CRCs on all the Ogg pages in a stream.
+  This is mostly useful if the stream has been edited with some non-
+  aware tool.
+
   rogg_pagedump dumps some basic header information for each page
   in a stream.
 
+  rogg_serial changes the serial of a logical ogg stream.
+

Added: experimental/giles/rogg/rogg_serial.c
===================================================================
--- experimental/giles/rogg/rogg_serial.c	                        (rev 0)
+++ experimental/giles/rogg/rogg_serial.c	2009-02-26 19:51:14 UTC (rev 15722)
@@ -0,0 +1,159 @@
+/*
+   Copyright (C) 2007 Xiph.org Foundation
+   Copyright (C) 2009 Joern 'manx' Heusipp
+
+   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.
+
+   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.
+*/
+
+/* ogg logical stream serial number mod script using the rogg library */
+
+/* compile with
+   gcc -O2 -g -Wall -I. -o rogg_changeserial rogg.c rogg_changeserial.c
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <rogg.h>
+
+unsigned int old_serial = 0;
+unsigned int new_serial = 0;
+
+void print_usage(FILE *out, char *name)
+{
+  fprintf(stderr, "Script for editing ogg headers\n");
+  fprintf(stderr, "%s [-s old:new] <file1.ogg> [<file2.ogg>...]\n",
+	name);
+  fprintf(stderr, 
+		  "    -s old:new  change the serial numer of a logical stream from old to new\n"
+		  "                (use hex values, e.g. 0x89ab4567:0x0123cdef)\n"
+		  "\n");
+}
+
+int parse_args(int *argc, char *argv[])
+{
+  int arg = 1;
+  int shift;
+
+  while (arg < *argc) {
+    shift = 0;
+    if (argv[arg][0] == '-') {
+      switch (argv[arg][1]) {
+	case 's':
+	  /* read serial numbers from the next arg */
+	  if (sscanf(argv[arg+1], "%x:%x", &old_serial, &new_serial) !=2 ) {
+	    fprintf(stderr, "Could not parse serial numbers '%s'.\n", argv[arg+1]);
+	    fprintf(stderr, "Try something like 0x89ab4567:0x0123cdef\n\n");
+	    old_serial = 0;
+	    new_serial = 0;
+	  } else {
+	    fprintf(stdout, "Changing serial 0x%08x to 0x%08x\n", old_serial, new_serial);
+	  }
+	  shift = 2;
+	  break;
+      }
+    }
+    if (shift) {
+      memmove(&argv[arg],&argv[arg+shift],shift*sizeof(*argv));
+      *argc -= shift;
+    } else {
+      arg++;
+    }
+  }
+
+  return 0;
+}
+
+int main(int argc, char *argv[])
+{
+  int f, i;
+  unsigned char *p, *q, *o, *e;
+  struct stat s;
+  rogg_page_header header;
+  uint32_t serial;
+
+  parse_args(&argc, argv);
+  if (argc < 2) {
+    print_usage(stderr, argv[0]);
+    exit(1);
+  }
+
+  for (i = 1; i < argc; i++) {
+    f = open(argv[i], O_RDWR);
+    if (f < 0) {
+	fprintf(stderr, "couldn't open '%s'\n", argv[i]);
+	continue;
+    }
+    if (fstat(f, &s) < 0) {
+	fprintf(stderr, "couldn't stat '%s'\n", argv[i]);
+	close(f);
+	continue;
+    }
+    p = mmap(0, s.st_size, PROT_READ|PROT_WRITE,
+	MAP_SHARED, f, 0);
+    if (p == NULL) {
+	fprintf(stderr, "couldn't mmap '%s'\n", argv[i]);
+	close(f);
+	continue;
+    }
+    fprintf(stdout, "Checking Ogg file '%s'\n", argv[i]);
+    e = p + s.st_size; /* pointer to the end of the file */
+    q = rogg_scan(p, s.st_size); /* scan for an Ogg page */
+    if (q == NULL) {
+	fprintf(stdout, "couldn't find ogg data!\n");
+    } else {
+      if (q > p) {
+	fprintf(stdout, "Skipped %d garbage bytes at the start\n", (int)(q-p));
+      } 
+      while (q < e) {
+	o = rogg_scan(q, e-q); /* find the next Ogg page */
+	if (o > q) {
+	  fprintf(stdout, "Hole in data! skipped %d bytes\n", (int)(o-q));
+	   q = o;
+	} else if (o == NULL) {
+	  fprintf(stdout, "Skipped %d garbage bytes as the end\n", (int)(e-q));
+	  break;
+	}
+	rogg_page_parse(q, &header);
+	rogg_read_uint32(&q[ROGG_OFFSET_SERIALNO], &serial);
+	if (serial == old_serial) {
+          rogg_write_uint32(&q[ROGG_OFFSET_SERIALNO], new_serial);
+          rogg_page_update_crc(q);
+	}
+	q += header.length;
+      }
+    }
+    munmap(p, s.st_size);
+    close(f);
+  }
+  return 0;
+}



More information about the commits mailing list