]> git.sesse.net Git - casparcg/blob - modules/flash/util/swf.cpp
de325157cace6ae5cec7ae09f3be92a78bc3b8b4
[casparcg] / modules / flash / util / swf.cpp
1 /*\r
2 * Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>\r
3 *\r
4 * This file is part of CasparCG (www.casparcg.com).\r
5 *\r
6 * CasparCG is free software: you can redistribute it and/or modify\r
7 * it under the terms of the GNU General Public License as published by\r
8 * the Free Software Foundation, either version 3 of the License, or\r
9 * (at your option) any later version.\r
10 *\r
11 * CasparCG is distributed in the hope that it will be useful,\r
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14 * GNU General Public License for more details.\r
15 *\r
16 * You should have received a copy of the GNU General Public License\r
17 * along with CasparCG. If not, see <http://www.gnu.org/licenses/>.\r
18 *\r
19 * Author: Robert Nagy, ronag89@gmail.com\r
20 */\r
21 \r
22 #include "../StdAfx.h"\r
23 \r
24 #include <common/except.h>\r
25 \r
26 #include <zlib.h> // Compiled into FreeImage\r
27 \r
28 #include <fstream>\r
29 #include <streambuf>\r
30 \r
31 namespace caspar { namespace flash {\r
32         \r
33 std::vector<char> decompress_one_file(const std::vector<char>& in_data, uLong buf_size = 5000000)\r
34 {\r
35         if(buf_size > 300*1000000)\r
36                 CASPAR_THROW_EXCEPTION(file_read_error());\r
37 \r
38         std::vector<char> out_data(buf_size, 0);\r
39 \r
40         auto ret = uncompress(reinterpret_cast<Bytef*>(out_data.data()), &buf_size, reinterpret_cast<const Bytef*>(in_data.data()), static_cast<uLong>(in_data.size()));\r
41 \r
42         if(ret == Z_BUF_ERROR)\r
43                 return decompress_one_file(in_data, buf_size*2);\r
44 \r
45         if(ret != Z_OK)\r
46                 CASPAR_THROW_EXCEPTION(file_read_error());\r
47 \r
48         out_data.resize(buf_size);\r
49 \r
50         return out_data;\r
51 }\r
52 \r
53 std::string read_template_meta_info(const std::wstring& filename)\r
54 {\r
55         auto file = std::fstream(filename, std::ios::in | std::ios::binary);\r
56 \r
57         if(!file)\r
58                 CASPAR_THROW_EXCEPTION(file_read_error());\r
59         \r
60         char head[4] = {};\r
61         file.read(head, 3);\r
62         \r
63         std::vector<char> data;\r
64         \r
65         file.seekg(0, std::ios::end);   \r
66         data.reserve(static_cast<size_t>(file.tellg()));\r
67         file.seekg(0, std::ios::beg);\r
68 \r
69         if(strcmp(head, "CWS") == 0)\r
70         {\r
71                 file.seekg(8, std::ios::beg);\r
72                 std::copy((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>(), std::back_inserter(data));\r
73                 data = decompress_one_file(data);\r
74         }\r
75         else\r
76         {\r
77                 file.seekg(0, std::ios::end);   \r
78                 data.reserve(static_cast<size_t>(file.tellg()));\r
79                 file.seekg(0, std::ios::beg);\r
80 \r
81                 std::copy((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>(), std::back_inserter(data));\r
82         }\r
83         \r
84         std::string beg_str = "<template version";\r
85         std::string end_str = "</template>";\r
86         auto beg_it = std::find_end(data.begin(), data.end(), beg_str.begin(), beg_str.end());\r
87         auto end_it = std::find_end(beg_it, data.end(), end_str.begin(), end_str.end());\r
88         \r
89         if(beg_it == data.end() || end_it == data.end())\r
90                 CASPAR_THROW_EXCEPTION(file_read_error());\r
91                         \r
92         return std::string(beg_it, end_it+end_str.size());\r
93 }\r
94 \r
95 }}