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