changeset 11924:217d10ec0e18

avi-fix v0.1: simple tool to fix chunk sizes in a RIFF AVI file
author arpi
date Thu, 05 Feb 2004 22:37:43 +0000
parents e9ab21c4db24
children 003959ebfcd7
files TOOLS/avi-fix.c
diffstat 1 files changed, 136 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TOOLS/avi-fix.c	Thu Feb 05 22:37:43 2004 +0000
@@ -0,0 +1,136 @@
+// avi-fix v0.1 (C) A'rpi, license GPL
+// simple tool to fix chunk sizes in a RIFF AVI file
+// it doesn't check/fix index, use mencoder -forceidx -oac copy -ovc copy to fix index!
+
+#include <stdio.h>
+#include <stdlib.h>
+//#include <string.h>
+
+#define FCC(a,b,c,d)  (((a)<<24)|((b)<<16)|((c)<<8)|(d))
+
+static inline xx(unsigned char c){
+    if(c>=32 && c<128) return c;
+    return '?';
+}
+
+static inline unsigned int getid(FILE* f){
+    unsigned int id;
+    id=fgetc(f);
+    id=(id<<8)|fgetc(f);
+    id=(id<<8)|fgetc(f);
+    id=(id<<8)|fgetc(f);
+    return id;
+}
+
+int main(int argc,char* argv[]){
+//FILE* f=fopen("edgar.avi","rb");  // readonly (report errors)
+//FILE* f=fopen("edgar.avi","rb+"); // fix mode (fix chunk sizes)
+unsigned int lastgood=0;
+unsigned int fixat=0;
+unsigned int offset=0;
+int fix_flag=0;
+FILE* f;
+
+if(argc<=1){
+    printf("Usage: %s [-fix] badfile.avi\n",argv[0]);
+    exit(1);
+}
+
+if(!strcmp(argv[1],"-fix")){
+    fix_flag=1;
+    f=fopen(argv[argc-1],"rb+");
+} else
+    f=fopen(argv[argc-1],"rb");
+
+if(!f){
+    perror("error");
+    printf("couldnt open '%s'\n",argv[argc-1]);
+    exit(2);
+}
+
+while(1){
+    unsigned int id,len;
+again:
+    id=fgetc(f);
+    id=(id<<8)|fgetc(f);
+    id=(id<<8)|fgetc(f);
+faszom:
+    if(feof(f)) break;
+//    if(!lastgood && feof(f)) break;
+    id=(id<<8)|fgetc(f);
+//    lastgood=ftell(f);
+    printf("%08X: %c%c%c%c\n",(int)ftell(f)-4,xx(id>>24),xx(id>>16),xx(id>>8),xx(id));
+    switch(id){
+    case FCC('R','I','F','F'):
+	fread(&len,4,1,f); // filesize
+	id=getid(f);  // AVI
+	printf("RIFF header, filesize=0x%X  format=%c%c%c%c\n",len,xx(id>>24),xx(id>>16),xx(id>>8),xx(id));
+	break;
+    case FCC('L','I','S','T'):
+	fread(&len,4,1,f); // size
+	id=getid(f);  // AVI
+	printf("LIST size=0x%X  format=%c%c%c%c\n",len,xx(id>>24),xx(id>>16),xx(id>>8),xx(id));
+	//case FCC('h','d','r','l'):
+	//case FCC('s','t','r','l'):
+	//case FCC('o','d','m','l'):
+	//case FCC('m','o','v','i'):
+	break;
+    // legal chunk IDs:
+    case FCC('a','v','i','h'): // avi header
+    case FCC('s','t','r','h'): // stream header
+    case FCC('s','t','r','f'): // stream format
+    case FCC('J','U','N','K'): // official shit
+    // index:
+    case FCC('i','d','x','1'): // main index??
+    case FCC('d','m','l','h'): // opendml header
+    case FCC('i','n','d','x'): // opendml main index??
+    case FCC('i','x','0','0'): // opendml sub index??
+    case FCC('i','x','0','1'): // opendml sub index??
+    // data:
+    case FCC('0','1','w','b'): // audio track #1
+    case FCC('0','2','w','b'): // audio track #2
+    case FCC('0','3','w','b'): // audio track #3
+    case FCC('0','0','d','b'): // uncompressed video
+    case FCC('0','0','d','c'): // compressed video
+    case FCC('0','0','_','_'): // A-V interleaved (type2 DV file)
+    // info:
+    case FCC('I','S','F','T'): // INFO: software
+    case FCC('I','S','R','C'): // INFO: source
+    case FCC('I','N','A','M'): // INFO: name
+    case FCC('I','S','B','J'): // INFO: subject
+    case FCC('I','A','R','T'): // INFO: artist
+    case FCC('I','C','O','P'): // INFO: copyright
+    case FCC('I','C','M','T'): // INFO: comment
+	lastgood=ftell(f);
+	if(fixat && fix_flag){
+	    // fix last chunk's size field:
+	    fseek(f,fixat,SEEK_SET);
+	    len=lastgood-fixat-8;
+	    printf("Correct len to 0x%X\n",len);
+	    fwrite(&len,4,1,f);
+	    fseek(f,lastgood,SEEK_SET);
+	    fixat=0;
+	}
+	fread(&len,4,1,f); // size
+	printf("ID ok, chunk len=0x%X\n",len);
+	len+=len&1; // align at 2
+	fseek(f,len,SEEK_CUR); // skip data
+	break;
+    default:
+	if(!lastgood){
+	    ++offset;
+	    printf("invalid ID, trying %d byte offset\n",offset);
+	    goto faszom; // try again @ next post
+	}
+	printf("invalid ID, parsing next chunk's data at 0x%X\n",lastgood);
+	fseek(f,lastgood,SEEK_SET);
+	fixat=lastgood;
+	lastgood=0;
+	goto again;
+    }
+    offset=0;
+}
+
+
+}
+