1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
// 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 "config.h"
#ifdef MP_DEBUG
#define mp_debug(...) printf(__VA_ARGS__)
#else
#define mp_debug(...)
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FCC(a,b,c,d) (((a)<<24)|((b)<<16)|((c)<<8)|(d))
static inline char 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);
mp_debug("%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
mp_debug("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
mp_debug("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;
mp_debug("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
mp_debug("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;
mp_debug("invalid ID, trying %d byte offset\n",offset);
goto faszom; // try again @ next post
}
mp_debug("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;
}
return 0;
}
|