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