Fix integer overflow in ft_rendered_size_line
[ilaris-y4m-tools.git] / dedup.cpp
blob6ca505903e6cc09c098d8f8c800686d777928109
1 #include "yuv4mpeg.hpp"
2 #include "parseval.hpp"
3 #include <iostream>
5 int main(int argc, char** argv)
7 uint64_t infr = 0;
8 uint64_t outfr = 0;
9 unsigned maxelide = 11;
10 size_t framesize = 0;
11 for(int i = 1; i < argc; i++) {
12 std::string arg = argv[i];
13 regex_results r;
14 if(r = regex("--max=(0|[1-9][0-9]*)", arg)) {
15 try {
16 maxelide = parse_value<unsigned>(r[1]);
17 } catch(std::exception& e) {
18 std::cerr << "dedup: Bad max dedup '" << r[1] << "'" << std::endl;
19 return 1;
21 } else {
22 std::cerr << "dedup: Unrecognized option '" << arg << "'" << std::endl;
23 return 1;
27 //Open files.
28 FILE* in = stdin;
29 FILE* out = stdout;
30 mark_pipe_as_binary(in);
31 mark_pipe_as_binary(out);
33 //Fixup header.
34 try {
35 struct yuv4mpeg_stream_header strmh(in);
36 if(strmh.chroma == "rgb")
37 framesize = 3 * strmh.width * strmh.height;
38 else if(strmh.chroma == "420")
39 framesize = 3 * strmh.width * strmh.height / 2;
40 else if(strmh.chroma == "420p16")
41 framesize = 6 * strmh.width * strmh.height / 2;
42 else if(strmh.chroma == "422")
43 framesize = 2 * strmh.width * strmh.height;
44 else if(strmh.chroma == "422p16")
45 framesize = 4 * strmh.width * strmh.height;
46 else if(strmh.chroma == "444")
47 framesize = 3 * strmh.width * strmh.height;
48 else if(strmh.chroma == "444p16")
49 framesize = 6 * strmh.width * strmh.height;
50 else
51 throw std::runtime_error("Unsupported input chroma type '" + strmh.chroma + "'");
52 if(strmh.find_extension("VFR"))
53 throw std::runtime_error("Can't dedup already VFR streams");
54 strmh.extension.push_back("VFR");
55 std::string _strmh = std::string(strmh);
56 write_or_die(out, _strmh);
58 unsigned duration = 0;
59 bool first = true;
60 std::string _framh, _framh2;
61 std::vector<char> buffer;
62 std::vector<char> buffer3;
63 buffer.resize(framesize);
64 buffer3.resize(framesize);
65 //Write frames.
66 while(true) {
67 if(!read_line2(in, _framh))
68 break;
69 _framh2 = _framh;
70 infr++;
71 read_or_die(in, &buffer3[0], buffer3.size());
72 if(duration == maxelide + 1)
73 goto different;
74 if(!first && memcmp(&buffer[0], &buffer3[0], framesize))
75 goto different;
76 if(first) {
77 memcpy(&buffer[0], &buffer3[0], framesize);
78 first = false;
80 duration++;
81 continue;
82 different:
83 outfr++;
84 struct yuv4mpeg_frame_header framh(_framh);
85 framh.duration = duration;
86 std::string _framh2 = framh;
87 write_or_die(out, _framh2);
88 write_or_die(out, &buffer[0], framesize);
89 memcpy(&buffer[0], &buffer3[0], framesize);
90 duration = 1;
92 if(duration) {
93 outfr++;
94 struct yuv4mpeg_frame_header framh(_framh2);
95 framh.duration = duration;
96 _framh = framh;
97 write_or_die(out, _framh);
98 write_or_die(out, &buffer3[0], framesize);
100 } catch(std::exception& e) {
101 std::cerr << "dedup: Error: " << e.what() << std::endl;
102 return 1;
104 std::cerr << "Dedup: Read " << infr << " frames, wrote " << outfr << " frames." << std::endl;
105 return 0;