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