synced with r24310
[mplayer/glamo.git] / TOOLS / subrip.c
blobed1161900ed5c3ecb977afaa5c2de899c520385e
1 /* -*- compile-command: "gcc -g -Wall -I.. -o subrip subrip.c ../vobsub.o ../spudec.o ../mp_msg.o ../unrarlib.o ../libswscale/swscale.o ../libswscale/rgb2rgb.o ../libswscale/yuv2rgb.o ../libmpcodecs/img_format.o -lm" -*- */
2 /*
3 * Use with CVS JOCR/GOCR.
5 * You will have to change 'vobsub_id' value if you want another subtitle than number 0.
7 * HINT: you can view the subtitle that is being decoded with "display subtitle-*.pgm"
9 */
11 /* Make sure this accesses the CVS version of JOCR/GOCR */
12 #define GOCR_PROGRAM "gocr"
14 #include <ctype.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <unistd.h>
19 #include <sys/types.h>
20 #include <sys/wait.h>
21 #include "libvo/video_out.h"
22 #include "vobsub.h"
23 #include "spudec.h"
25 void guiMessageBox(int level, char * str) {};
27 /* XXX Kludge ahead, this MUST be the same as the definitions found in ../spudec.c */
28 typedef struct packet_t packet_t;
29 struct packet_t {
30 unsigned char *packet;
31 unsigned int palette[4];
32 unsigned int alpha[4];
33 unsigned int control_start; /* index of start of control data */
34 unsigned int current_nibble[2]; /* next data nibble (4 bits) to be
35 processed (for RLE decoding) for
36 even and odd lines */
37 int deinterlace_oddness; /* 0 or 1, index into current_nibble */
38 unsigned int start_col, end_col;
39 unsigned int start_row, end_row;
40 unsigned int width, height, stride;
41 unsigned int start_pts, end_pts;
42 packet_t *next;
44 typedef struct {
45 packet_t *queue_head;
46 packet_t *queue_tail;
47 unsigned int global_palette[16];
48 unsigned int orig_frame_width, orig_frame_height;
49 unsigned char* packet;
50 size_t packet_reserve; /* size of the memory pointed to by packet */
51 unsigned int packet_offset; /* end of the currently assembled fragment */
52 unsigned int packet_size; /* size of the packet once all fragments are assembled */
53 unsigned int packet_pts; /* PTS for this packet */
54 unsigned int palette[4];
55 unsigned int alpha[4];
56 unsigned int cuspal[4];
57 unsigned int custom;
58 unsigned int now_pts;
59 unsigned int start_pts, end_pts;
60 unsigned int start_col, end_col;
61 unsigned int start_row, end_row;
62 unsigned int width, height, stride;
63 size_t image_size; /* Size of the image buffer */
64 unsigned char *image; /* Grayscale value */
65 unsigned char *aimage; /* Alpha value */
66 unsigned int scaled_frame_width, scaled_frame_height;
67 unsigned int scaled_start_col, scaled_start_row;
68 unsigned int scaled_width, scaled_height, scaled_stride;
69 size_t scaled_image_size;
70 unsigned char *scaled_image;
71 unsigned char *scaled_aimage;
72 int auto_palette; /* 1 if we lack a palette and must use an heuristic. */
73 int font_start_level; /* Darkest value used for the computed font */
74 vo_functions_t *hw_spu;
75 int spu_changed;
76 } spudec_handle_t;
78 int use_gui;
79 int gtkMessageBox;
80 int identify=0;
81 int vobsub_id=0;
82 int sub_pos=0;
84 static spudec_handle_t *spudec;
85 static FILE *fsub = NULL;
86 static unsigned int sub_idx = 0;
88 static void
89 process_gocr_output(const char *const fname, unsigned int start, unsigned int end)
91 FILE *file;
92 int temp, h, m, s, ms;
93 int c, bol;
94 file = fopen(fname, "r");
95 if (file == NULL) {
96 perror("fopen failed");
97 return;
99 temp = start;
100 temp /= 90;
101 h = temp / 3600000;
102 temp %= 3600000;
103 m = temp / 60000;
104 temp %= 60000;
105 s = temp / 1000;
106 temp %= 1000;
107 ms = temp;
108 fprintf(fsub, "%d\n%02d:%02d:%02d,%03d --> ", ++sub_idx, h, m, s, ms);
109 temp = end;
110 temp /= 90;
111 h = temp / 3600000;
112 temp %= 3600000;
113 m = temp / 60000;
114 temp %= 60000;
115 s = temp / 1000;
116 temp %= 1000;
117 ms = temp;
118 fprintf(fsub, "%02d:%02d:%02d,%03d\n", h, m, s, ms);
119 bol = 1;
120 while ((c = getc(file)) != EOF) {
121 if (bol) {
122 if (!isspace(c)) {
123 putc(c, fsub);
124 bol=0;
127 else if (!bol) {
128 putc(c, fsub);
129 bol = c == '\n';
132 putc('\n', fsub);
133 fflush(fsub);
134 fclose(file);
137 static void
138 output_pgm(FILE *f, int w, int h, unsigned char *src, unsigned char *srca, int stride)
140 int x, y;
141 fprintf(f,
142 "P5\n"
143 "%d %d\n"
144 "255\n",
145 w, h);
146 for (y = 0; y < h; ++y) {
147 for (x = 0; x < w; ++x) {
148 int res;
149 if (srca[x])
150 res = src[x] * (256 - srca[x]);
151 else
152 res = 0;
153 res = (65535 - res) >> 8;
154 putc(res&0xff, f);
157 src += stride;
158 srca += stride;
160 putc('\n', f);
163 static void
164 draw_alpha(int x0, int y0, int w, int h, unsigned char *src, unsigned char *srca, int stride)
166 FILE *f;
167 char buf[128];
168 char cmd[512];
169 int cmdres;
170 const char *const tmpfname = tmpnam(NULL);
171 sprintf(buf, "subtitle-%d-%d.pgm", spudec->start_pts / 90, spudec->end_pts / 90);
172 f = fopen(buf, "w");
173 output_pgm(f, w, h, src, srca, stride);
174 fclose(f);
175 /* see <URL:http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/subtitleripper/subtitleripper/src/README.gocr?rev=HEAD&content-type=text/vnd.viewcvs-markup> */
176 sprintf(cmd, GOCR_PROGRAM" -v 1 -s 7 -d 0 -m 130 -m 256 -m 32 -i %s -o %s", buf, tmpfname);
177 cmdres = system(cmd);
178 if (cmdres < 0) {
179 perror("system failed");
180 exit(EXIT_FAILURE);
182 else if (cmdres) {
183 fprintf(stderr, GOCR_PROGRAM" returned %d\n", cmdres);
184 exit(cmdres);
186 process_gocr_output(tmpfname, spudec->start_pts, spudec->end_pts);
187 unlink(buf);
188 unlink(tmpfname);
191 void
192 fast_memcpy(void *a, void *b, int s)
193 { //FIXME
194 memcpy(a, b, s);
198 main(int argc, char **argv)
200 const char *vobsubname, *subripname;
201 void *vobsub;
202 void *packet;
203 int packet_len;
204 unsigned int pts100;
206 if (argc < 2 || 4 < argc) {
207 fprintf(stderr, "Usage: %s <vobsub basename> [<subid> [<output filename>] ]\n", argv[0]);
208 exit(EXIT_FAILURE);
210 vobsubname = argv[1];
211 subripname = NULL;
212 fsub = stdout;
213 if (argc >= 3)
214 vobsub_id = atoi(argv[2]);
215 if (argc >= 4) {
216 subripname = argv[3];
217 fsub = fopen(subripname, "w");
220 vobsub = vobsub_open(vobsubname, NULL, 0, &spudec);
221 while ((packet_len=vobsub_get_next_packet(vobsub, &packet, &pts100)) >= 0) {
222 spudec_assemble(spudec, packet, packet_len, pts100);
223 if (spudec->queue_head) {
224 spudec_heartbeat(spudec, spudec->queue_head->start_pts);
225 if (spudec_changed(spudec))
226 spudec_draw(spudec, draw_alpha);
230 if (vobsub)
231 vobsub_close(vobsub);
232 exit(EXIT_SUCCESS);