[xiph-commits] r11096 - experimental/giles/mng
giles at svn.xiph.org
giles at svn.xiph.org
Tue Apr 4 15:00:41 PDT 2006
Author: giles
Date: 2006-04-04 15:00:40 -0700 (Tue, 04 Apr 2006)
New Revision: 11096
Added:
experimental/giles/mng/mng.c
Modified:
experimental/giles/mng/Makefile
Log:
Quick-and-dirty MNG -> Ogg MNG encapsulation utility. Does not set
granulepos.
Call like so: './mng input.mng > output.ogg'. When called with no
arguments, input.mng is read from stdin.
Modified: experimental/giles/mng/Makefile
===================================================================
--- experimental/giles/mng/Makefile 2006-04-04 20:36:50 UTC (rev 11095)
+++ experimental/giles/mng/Makefile 2006-04-04 22:00:40 UTC (rev 11096)
@@ -1,6 +1,6 @@
# GNU makefile for mng stuff
-PROGS = mngplay
+PROGS = mngplay mng
CFLAGS = -g -O2 -Wall
@@ -9,6 +9,10 @@
mngplay_CFLAGS = `sdl-config --cflags`
mngplay_LIBS = `sdl-config --libs` -lmng -lz -ljpeg -llcms -logg
+mng_SRCS = mng.c
+mng_OBJS = $(mng_SRCS:.c=.o)
+mng_LIBS = -logg
+
all : $(PROGS)
clean :
@@ -20,3 +24,7 @@
mngplay : CFLAGS += $(mngplay_CFLAGS)
mngplay : LDFLAGS += $(mngplay_LIBS)
mngplay : $(mngplay_OBJS)
+
+mng : CFLAGS += $(mng_CFLAGS)
+mng : LDFLAGS += $(mng_LIBS)
+mng : $(mng_OBJS)
Added: experimental/giles/mng/mng.c
===================================================================
--- experimental/giles/mng/mng.c 2006-04-04 20:36:50 UTC (rev 11095)
+++ experimental/giles/mng/mng.c 2006-04-04 22:00:40 UTC (rev 11096)
@@ -0,0 +1,180 @@
+/* Copyright (C) 2006 Xiph.org Foundation
+
+ MNG encode and playback utility
+
+ Distributed under the terms of the GPL v2 or later.
+*/
+
+/* $Id: $ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <time.h>
+
+#if 0
+/* note: we require libmng version 1.0.8 or later for the Ogg MNG stuff */
+#include <libmng.h>
+
+/* SDL playback support is optional */
+#ifdef HAVE_SDL
+#include <SDL.h>
+#endif
+#endif
+
+#include <ogg/ogg.h>
+
+#define PNG_SIGNATURE "\211PNG\r\n\032\n"
+#define MNG_SIGNATURE "\212MNG\r\n\032\n"
+#define JNG_SIGNATURE "\213JNG\r\n\032\n"
+
+#define BUFFER_SIZE 4096
+
+/* for now, just convert mng to oggmng */
+
+int read_uint32(FILE *in, uint32_t *value)
+{
+ unsigned char data[4];
+ int bytes;
+
+ bytes = fread(data, 1, 4, in);
+ if (bytes != 4) return -1;
+
+ *value = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
+
+ return 0;
+}
+
+int put_uint32(unsigned char *buffer, uint32_t value)
+{
+ buffer[0] = (value >> 24) & 0xFF;
+ buffer[1] = (value >> 16) & 0xFF;
+ buffer[2] = (value >> 8) & 0xFF;
+ buffer[3] = (value ) & 0xFF;
+
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ FILE *in, *out;
+ char *infilename, *outfilename;
+ ogg_stream_state os;
+ ogg_page og;
+ ogg_packet op;
+ unsigned char magic[8];
+ unsigned char *buffer;
+ int bytes, ret;
+ uint32_t type, length, crc;
+ long packetno;
+
+ if (argc < 2) {
+ in = stdin;
+ } else {
+ infilename = argv[1];
+ in = fopen(infilename, "rb");
+ if (in == NULL) {
+ fprintf(stderr, "unable to open input file '%s'\n",
+ infilename);
+ exit(2);
+ }
+ }
+
+ out = stdout;
+
+ srand(clock());
+ ogg_stream_init(&os, rand());
+
+ /* first packet is special */
+ bytes = fread(magic, 1, 8, in);
+ if (bytes != 8) {
+ fprintf(stderr, "couldn't read file magic!\n");
+ exit(3);
+ }
+ /* verify file magic */
+ if (!memcmp(magic, MNG_SIGNATURE, 8)) {
+ fprintf(stderr, "Encapsulating MNG file\n");
+ } else if (!memcmp(magic, PNG_SIGNATURE, 8)) {
+ fprintf(stderr, "Encapsulating PNG file\n");
+ } else if (!memcmp(magic, JNG_SIGNATURE, 8)) {
+ fprintf(stderr, "Encapsulating JNG file\n");
+ } else {
+ fprintf(stderr, "Unrecognized file type!\n");
+ }
+
+ /* get the MHDR */
+ ret = read_uint32(in, &length);
+ if (length != 28) {
+ fprintf(stderr, "warning: MHDR is %d bytes instead of 28\n",
+ bytes - 4);
+ }
+ /* be slightly permissive on spec breakage */
+ if (length > 10240) {
+ fprintf(stderr, "error: MHDR unreasonably large, aborting.\n");
+ return 4;
+ }
+ buffer = malloc(length + 8 + 4);
+ memcpy(buffer, magic, 8);
+ bytes = fread(buffer+8, 1, length + 4, in);
+ if (bytes != length + 4) {
+ fprintf(stderr, "i/o error: unexpected end of MHDR\n");
+ }
+ ret = read_uint32(in, &crc);
+ /* todo; verify crc */
+ fprintf(stderr, "chunk %c%c%c%c %d bytes\tcrc %08x\n",
+ buffer[8], buffer[9], buffer[10], buffer[11],
+ bytes - 4, crc);
+ op.packet = buffer;
+ op.bytes = 8 + bytes;
+ op.b_o_s = 1;
+ op.e_o_s = 0;
+ op.granulepos = -1;
+ op.packetno = packetno = 0;
+ ogg_stream_packetin(&os, &op);
+ free(buffer); /* libogg copies the data */
+ /* we'll take care of writing this out in the main loop below */
+
+ while (!feof(in)) {
+ ret = read_uint32(in, &length);
+ if (ret && feof(in)) break; /* no more data */
+ buffer = malloc(length + 4);
+ bytes = fread(buffer, 1, length+4, in);
+ if (bytes != length+4) {
+ fprintf(stderr, "i/o error: unexpected end of data"
+ ", read %d of %d bytes.\n", bytes, length+4);
+ break;
+ }
+ ret = read_uint32(in, &crc);
+ /* todo: verify crc */
+ fprintf(stderr, "chunk %c%c%c%c %d bytes\tcrc %08x\n",
+ buffer[0], buffer[1], buffer[2], buffer[3],
+ bytes - 4, crc);
+ op.packet = buffer;
+ op.bytes = bytes;
+ op.b_o_s = 0;
+ op.e_o_s = feof(in); /* set eos flag on the last packet */
+ op.granulepos = -1;
+ op.packetno = packetno++;
+ ogg_stream_packetin(&os, &op);
+ free(buffer);
+
+ /* write out any completed Ogg pages */
+ while (ogg_stream_pageout(&os, &og) > 0) {
+ fwrite(og.header, 1, og.header_len, out);
+ fwrite(og.body, 1, og.body_len, out);
+ }
+ }
+
+ /* flush any remaining pages */
+ while (ogg_stream_flush(&os, &og) > 0) {
+ fwrite(og.header, 1, og.header_len, out);
+ fwrite(og.body, 1, og.body_len, out);
+ }
+
+ ogg_stream_clear(&os);
+
+ if (in != stdin) fclose(in);
+
+ return 0;
+}
More information about the commits
mailing list