Fix integer overflow in ft_rendered_size_line
[ilaris-y4m-tools.git] / subtitle.cpp
blobf72020ee4e47cd973e6ef9cc691cd56f8d8b1f74
1 #include "yuv4mpeg.hpp"
2 #include "parseval.hpp"
3 #include "marker.hpp"
4 #include "rendertext.hpp"
5 #include <iostream>
7 int main(int argc, char** argv)
9 subtitle_render_context rctx;
10 std::vector<pre_subtitle*> presubs;
11 size_t framesize = 0;
12 for(int i = 1; i < argc; i++) {
13 std::string arg = argv[i];
14 try {
15 if(!rctx.argument(arg, presubs)) {
16 std::cerr << "subtitle: Unrecognized option '" << arg << "'" << std::endl;
17 return 1;
19 } catch(std::exception& e) {
20 std::cerr << "subtitle: Error in option '" << arg << "': " << e.what() << std::endl;
21 return 1;
25 //Open files.
26 FILE* in = stdin;
27 FILE* out = stdout;
28 mark_pipe_as_binary(in);
29 mark_pipe_as_binary(out);
31 //Fixup header.
32 try {
33 struct yuv4mpeg_stream_header strmh(in);
34 if(strmh.chroma == "rgb")
35 framesize = 3 * strmh.width * strmh.height;
36 else if(strmh.chroma == "420")
37 framesize = 3 * strmh.width * strmh.height / 2;
38 else if(strmh.chroma == "420p16")
39 framesize = 6 * strmh.width * strmh.height / 2;
40 else if(strmh.chroma == "422")
41 framesize = 2 * strmh.width * strmh.height;
42 else if(strmh.chroma == "422p16")
43 framesize = 4 * strmh.width * strmh.height;
44 else if(strmh.chroma == "444")
45 framesize = 3 * strmh.width * strmh.height;
46 else if(strmh.chroma == "444p16")
47 framesize = 6 * strmh.width * strmh.height;
48 else
49 throw std::runtime_error("Unsupported input chroma type '" + strmh.chroma + "'");
50 std::vector<subtitle*> subs = subtitle::from_presub(presubs, strmh);
51 write_or_die(out, static_cast<std::string>(strmh));
53 uint64_t curframe = 0;
54 std::string _framh, _framh2;
55 std::vector<char> buffer;
56 buffer.resize(framesize);
57 struct yuv4mpeg_frame_header framh;
59 //Frame loop.
60 while(true) {
61 regex_results r;
62 unsigned duration = 1;
63 if(!read_line2(in, _framh))
64 return 0; //End.
65 framh = yuv4mpeg_frame_header(_framh);
66 read_or_die(in, &buffer[0], buffer.size());
67 duration = framh.duration;
68 for(auto i : subs)
69 i->stamp(reinterpret_cast<uint8_t*>(&buffer[0]), strmh.width, strmh.height, curframe);
70 write_or_die(out, static_cast<std::string>(framh));
71 write_or_die(out, &buffer[0], buffer.size());
72 curframe += duration;
74 } catch(std::exception& e) {
75 std::cerr << "subtitle: Error: " << e.what() << std::endl;
76 return 1;
78 return 0;