sync with en/mplayer.1 r29555
[mplayer/glamo.git] / TOOLS / avisubdump.c
blob9606137e0c83a000f602e181518521012a8b8648
1 /*
2 * avisubdump
4 * avi vobsub subtitle stream dumper (c) 2004 Tobias Diedrich
5 * Licensed under GNU GPLv2 or (at your option) any later version.
7 * The subtitles are dumped to stdout.
8 */
10 #include <unistd.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <fcntl.h>
15 #include <errno.h>
17 #define FCC(a,b,c,d) (((a))|((b)<<8)|((c)<<16)|((d)<<24))
19 #define FCC_RIFF FCC('R','I','F','F')
20 #define FCC_LIST FCC('L','I','S','T')
21 #define FCC_strh FCC('s','t','r','h')
22 #define FCC_txts FCC('t','x','t','s')
23 #define FCC_GAB2 FCC('G','A','B','2')
25 #define GAB_LANGUAGE 0
26 #define GAB_ENTRY 1
27 #define GAB_LANGUAGE_UNICODE 2
28 #define GAB_ENTRY_UNICODE 3
29 #define GAB_RAWTEXTSUBTITLE 4
31 static unsigned int getle16(FILE* f){
32 unsigned int res;
34 res = fgetc(f);
35 res |= fgetc(f) << 8;
37 return res;
40 static unsigned int getle(FILE* f){
41 unsigned int res;
43 res = fgetc(f);
44 res |= fgetc(f) << 8;
45 res |= fgetc(f) << 16;
46 res |= fgetc(f) << 24;
48 return res;
51 static void skip(FILE *f, int len)
53 if (f != stdin) {
54 fseek(f,len,SEEK_CUR);
55 } else {
56 void *buf = malloc(len);
57 fread(buf,len,1,f);
58 free(buf);
62 static int stream_id(unsigned int id)
64 char c1,c2;
65 c1 = (char)(id & 0xff);
66 c2 = (char)((id >> 8) & 0xff);
67 if (c1 >= '0' && c1 <= '9' &&
68 c2 >= '0' && c2 <= '9') {
69 c1 -= '0';
70 c2 -= '0';
71 return c1*10+c2;
73 return -1;
76 static int dumpsub_gab2(FILE *f, int size) {
77 int ret = 0;
79 while (ret + 6 <= size) {
80 unsigned int len, id;
81 char *buf;
82 int i;
84 id = getle16(f); ret += 2;
85 len = getle(f); ret += 4;
86 if (ret + len > size) break;
88 buf = malloc(len);
89 ret += fread(buf, 1, len, f);
91 switch (id) {
92 case GAB_LANGUAGE_UNICODE: /* FIXME: convert to utf-8; endianness */
93 for (i=0; i<len; i++) buf[i] = buf[i*2];
94 case GAB_LANGUAGE:
95 fprintf(stderr, "LANGUAGE: %s\n", buf);
96 break;
97 case GAB_ENTRY_UNICODE: /* FIXME: convert to utf-8; endianness */
98 for (i=0; i<len; i++) buf[i] = buf[i*2];
99 case GAB_ENTRY:
100 fprintf(stderr, "ENTRY: %s\n", buf);
101 break;
102 case GAB_RAWTEXTSUBTITLE:
103 printf("%s", buf);
104 break;
105 default:
106 fprintf(stderr, "Unknown type %d, len %d\n", id, len);
107 break;
109 free(buf);
112 return ret;
115 static void dump(FILE *f) {
116 unsigned int id, len;
117 int stream = 0;
118 int substream = -2;
120 while (1) {
121 id = getle(f);
122 len = getle(f);
124 if(feof(f)) break;
126 if (id == FCC_RIFF ||
127 id == FCC_LIST) {
128 getle(f);
129 continue;
130 } else if (id == FCC_strh) {
131 id = getle(f); len -= 4;
132 fprintf(stderr, "Stream %d is %c%c%c%c",
133 stream,
135 id >> 8,
136 id >> 16,
137 id >> 24);
138 if (id == FCC_txts) {
139 substream = stream;
140 fprintf(stderr, " (subtitle stream)");
142 fprintf(stderr, ".\n");
143 stream++;
144 } else if (stream_id(id) == substream) {
145 unsigned int subid;
146 subid = getle(f); len -= 4;
147 if (subid != FCC_GAB2) {
148 fprintf(stderr,
149 "Unknown subtitle chunk %c%c%c%c (%08x).\n",
150 id, id >> 8, id >> 16, id >> 24, subid);
151 } else {
152 skip(f,1); len -= 1;
153 len -= dumpsub_gab2(f, len);
156 len+=len&1;
157 skip(f,len);
161 int main(int argc,char* argv[])
163 FILE* f;
165 if (argc != 2) {
166 fprintf(stderr, "Usage: %s <avi>\n", argv[0]);
167 exit(1);
170 if (strcmp(argv[argc-1], "-") == 0) f=stdin;
171 else f=fopen(argv[argc-1],"rb");
173 if (!f) {
174 fprintf(stderr, "Could not open '%s': %s\n",
175 argv[argc-1], strerror(errno));
176 exit(-errno);
179 dump(f);
181 return 0;