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