comparison Resources/EmbedStaticAssets.py @ 0:39585ba26f20

initial commit
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 15 Jun 2023 09:48:46 +0200
parents
children 154cb76a042f
comparison
equal deleted inserted replaced
-1:000000000000 0:39585ba26f20
1 #!/usr/bin/python3
2
3 # SPDX-FileCopyrightText: 2023 Sebastien Jodogne, UCLouvain, Belgium
4 # SPDX-License-Identifier: GPL-3.0-or-later
5
6 # OHIF plugin for Orthanc
7 # Copyright (C) 2023 Sebastien Jodogne, UCLouvain, Belgium
8 #
9 # This program is free software: you can redistribute it and/or
10 # modify it under the terms of the GNU General Public License as
11 # published by the Free Software Foundation, either version 3 of the
12 # License, or (at your option) any later version.
13 #
14 # This program is distributed in the hope that it will be useful, but
15 # WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 # General Public License for more details.
18 #
19 # You should have received a copy of the GNU General Public License
20 # along with this program. If not, see <http://www.gnu.org/licenses/>.
21
22
23 import gzip
24 import hashlib
25 import io
26 import os
27 import sys
28
29 if len(sys.argv) != 3:
30 raise Exception('Usage: %s [source folder] [target C++]' % sys.argv[0])
31
32 SOURCE = sys.argv[1]
33 TARGET = sys.argv[2]
34
35 if not os.path.isdir(SOURCE):
36 raise Exception('Nonexistent source folder: %s' % SOURCE)
37
38
39 def EncodeFileAsCString(f, variable, content):
40 f.write('static const uint8_t %s[%d] = \n "' % (variable, len(content) + 1))
41
42 column = 0
43
44 for c in content:
45
46 if sys.version_info < (3, 0):
47 # Python 2.7
48 i = ord(c)
49 else:
50 # Python 3.x
51 i = c
52
53 if i < 32 or i >= 127 or i == ord('?'):
54 f.write('\\{0:03o}'.format(i))
55 elif i in [ ord('"'), ord('\\') ]:
56 f.write('\\' + chr(i))
57 else:
58 f.write(chr(i))
59
60 column += 1
61 if column >= 120:
62 f.write('"\n "')
63 column = 0
64
65 f.write('";\n\n')
66
67
68 def WriteChecksum(f, variable, content):
69 md5 = hashlib.md5(content).hexdigest()
70 g.write('static const char* %s = "%s";\n\n' % (variable, md5))
71
72
73 with open(TARGET, 'w') as g:
74 g.write('''
75 #include <stdint.h>
76 #include <Compression/GzipCompressor.h>
77 #include <OrthancException.h>
78 #include <Toolbox.h>
79
80 static void Uncompress(std::string& target, const void* data, size_t size, const std::string& md5Expected)
81 {
82 Orthanc::GzipCompressor compressor;
83 compressor.Uncompress(target, data, size);
84 std::string md5Actual;
85 Orthanc::Toolbox::ComputeMD5(md5Actual, target);
86 if (md5Actual != md5Expected)
87 {
88 throw Orthanc::OrthancException(Orthanc::ErrorCode_CorruptedFile);
89 }
90 }
91
92 ''')
93
94 index = {}
95 count = 0
96
97 for root, dirs, files in os.walk(SOURCE):
98 for f in files:
99 fullPath = os.path.join(root, f)
100 relativePath = os.path.relpath(os.path.join(root, f), SOURCE)
101 variable = 'data_%06d' % count
102
103 with open(fullPath, 'rb') as source:
104 content = source.read()
105
106 if sys.version_info < (3, 0):
107 # Python 2.7
108 fileobj = io.BytesIO()
109 gzip.GzipFile(fileobj=fileobj, mode='w').write(content)
110 compressed = fileobj.getvalue()
111 else:
112 # Python 3.x
113 compressed = gzip.compress(content)
114
115 EncodeFileAsCString(g, variable, compressed)
116 WriteChecksum(g, variable + '_md5', content)
117
118 index[relativePath] = variable
119
120 count += 1
121
122 g.write('void ReadStaticAsset(std::string& target, const std::string& path)\n')
123 g.write('{\n')
124 for (path, variable) in index.items():
125 g.write(' if (path == "%s")\n' % path)
126 g.write(' {\n')
127 g.write(' Uncompress(target, %s, sizeof(%s) - 1, %s_md5);\n' % (variable, variable, variable))
128 g.write(' return;\n')
129 g.write(' }\n\n')
130
131 g.write(' throw Orthanc::OrthancException(Orthanc::ErrorCode_InexistentItem, "Unknown OHIF resource: " + path);\n')
132 g.write('}\n')