]> git.sesse.net Git - casparcg/blob - modules/flash/util/swf.cpp
d278a55573be029cab34da0b8adf37324f95983b
[casparcg] / modules / flash / util / swf.cpp
1 #include "../StdAfx.h"\r
2 \r
3 #include <common/exception/exceptions.h>\r
4 \r
5 #include <fstream>\r
6 #include <streambuf>\r
7 \r
8 #include <zlib.h>\r
9 \r
10 namespace caspar { namespace flash {\r
11         \r
12 std::vector<char> decompress_one_file(const std::vector<char>& in_data, uLong buf_size = 5000000)\r
13 {\r
14         if(buf_size > 300*1000000)\r
15                 BOOST_THROW_EXCEPTION(file_read_error());\r
16 \r
17         std::vector<char> out_data(buf_size, 0);\r
18 \r
19         auto ret = uncompress((Bytef*)out_data.data(), &buf_size, (Bytef*)in_data.data(), in_data.size());\r
20 \r
21         if(ret == Z_BUF_ERROR)\r
22                 return decompress_one_file(in_data, buf_size*2);\r
23 \r
24         if(ret != Z_OK)\r
25                 BOOST_THROW_EXCEPTION(file_read_error());\r
26 \r
27         out_data.resize(buf_size);\r
28 \r
29         return out_data;\r
30 }\r
31 \r
32 std::wstring read_swf_meta_info(const std::wstring& filename)\r
33 {\r
34         auto file = std::fstream(filename, std::ios::in | std::ios::binary);\r
35 \r
36         if(!file)\r
37                 BOOST_THROW_EXCEPTION(file_read_error());\r
38         \r
39         char head[4] = {};\r
40         file.read(head, 3);\r
41         \r
42         std::vector<char> data;\r
43         \r
44         file.seekg(0, std::ios::end);   \r
45         data.reserve(static_cast<size_t>(file.tellg()));\r
46         file.seekg(0, std::ios::beg);\r
47 \r
48         if(strcmp(head, "CWS") == 0)\r
49         {\r
50                 file.seekg(8, std::ios::beg);\r
51                 std::copy((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>(), std::back_inserter(data));\r
52                 data = decompress_one_file(data);\r
53         }\r
54         else\r
55         {\r
56                 file.seekg(0, std::ios::end);   \r
57                 data.reserve(static_cast<size_t>(file.tellg()));\r
58                 file.seekg(0, std::ios::beg);\r
59 \r
60                 std::copy((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>(), std::back_inserter(data));\r
61         }\r
62         \r
63         std::string beg_str = "<template version";\r
64         std::string end_str = "</template>";\r
65         auto beg_it = std::find_end(data.begin(), data.end(), beg_str.begin(), beg_str.end());\r
66         auto end_it = std::find_end(beg_it, data.end(), end_str.begin(), end_str.end());\r
67         \r
68         if(beg_it == data.end() || end_it == data.end())\r
69                 BOOST_THROW_EXCEPTION(file_read_error());\r
70         \r
71         return widen(std::string(beg_it, end_it+end_str.size()));\r
72 }\r
73 \r
74 }}