| #!/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: | |
| if isinstance(b, str): | |
| # python 2 | |
| yield ord(b) | |
| else: | |
| # python 3 | |
| yield 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 <stddef.h>\n') | |
| out('#include <stdint.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() |