huangcm
2025-09-01 53d8e046ac1bf2ebe94f671983e3d3be059df91a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#!/usr/bin/python
 
'''
Copyright 2015 Google Inc.
 
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
'''
 
import argparse
 
 
def bytes_from_file(f, chunksize=8192):
  while True:
    chunk = f.read(chunksize)
    if chunk:
      for b in chunk:
        yield ord(b)
    else:
      break
 
 
def main():
  parser = argparse.ArgumentParser(
      formatter_class=argparse.RawDescriptionHelpFormatter,
      description='Convert resource files to embedded read only data.',
      epilog='''The output (when compiled and linked) can be used as:
struct SkEmbeddedResource {const uint8_t* data; const size_t size;};
struct SkEmbeddedHeader {const SkEmbeddedResource* entries; const int count;};
extern "C" SkEmbeddedHeader const NAME;''')
  parser.add_argument('--align', default=1, type=int,
                      help='minimum alignment (in bytes) of resource data')
  parser.add_argument('--name', default='_resource', type=str,
                      help='the name of the c identifier to export')
  parser.add_argument('--input', required=True, type=argparse.FileType('rb'),
                      nargs='+', help='list of resource files to embed')
  parser.add_argument('--output', required=True, type=argparse.FileType('w'),
                      help='the name of the cpp file to output')
  args = parser.parse_args()
 
  out = args.output.write;
  out('#include "SkTypes.h"\n')
 
  # Write the resources.
  index = 0
  for f in args.input:
    out('alignas({1:d}) static const uint8_t resource{0:d}[] = {{\n'
        .format(index, args.align))
    bytes_written = 0
    bytes_on_line = 0
    for b in bytes_from_file(f):
      out(hex(b) + ',')
      bytes_written += 1
      bytes_on_line += 1
      if bytes_on_line >= 32:
        out('\n')
        bytes_on_line = 0
    out('};\n')
    out('static const size_t resource{0:d}_size = {1:d};\n'
        .format(index, bytes_written))
    index += 1
 
  # Write the resource entries.
  out('struct SkEmbeddedResource { const uint8_t* d; const size_t s; };\n')
  out('static const SkEmbeddedResource header[] = {\n')
  index = 0
  for f in args.input:
    out('  {{ resource{0:d}, resource{0:d}_size }},\n'.format(index))
    index += 1
  out('};\n')
  out('static const int header_count = {0:d};\n'.format(index))
 
  # Export the resource header.
  out('struct SkEmbeddedHeader {const SkEmbeddedResource* e; const int c;};\n')
  out('extern "C" const SkEmbeddedHeader {0:s} = {{ header, header_count }};\n'
      .format(args.name))
 
 
if __name__ == "__main__":
  main()