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