OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright 2015 The Chromium Authors. All rights reserved. | 2 # Copyright 2015 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 """Windows ICO file crusher. | 6 """Windows ICO file crusher. |
7 | 7 |
8 Optimizes the PNG images within a Windows ICO icon file. This extracts all of | 8 Optimizes the PNG images within a Windows ICO icon file. This extracts all of |
9 the sub-images within the file, runs any PNG-formatted images through | 9 the sub-images within the file, runs any PNG-formatted images through |
10 optimize-png-files.sh, then packs them back into an ICO file. | 10 optimize-png-files.sh, then packs them back into an ICO file. |
(...skipping 14 matching lines...) Expand all Loading... |
25 | 25 |
26 def main(args=None): | 26 def main(args=None): |
27 if args is None: | 27 if args is None: |
28 args = sys.argv[1:] | 28 args = sys.argv[1:] |
29 | 29 |
30 parser = argparse.ArgumentParser(description='Crush Windows ICO files.') | 30 parser = argparse.ArgumentParser(description='Crush Windows ICO files.') |
31 parser.add_argument('files', metavar='ICO', type=argparse.FileType('r+b'), | 31 parser.add_argument('files', metavar='ICO', type=argparse.FileType('r+b'), |
32 nargs='+', help='.ico files to be crushed') | 32 nargs='+', help='.ico files to be crushed') |
33 parser.add_argument('-o', dest='optimization_level', metavar='OPT', type=int, | 33 parser.add_argument('-o', dest='optimization_level', metavar='OPT', type=int, |
34 help='optimization level') | 34 help='optimization level') |
| 35 parser.add_argument('--lint', dest='lint', action='store_true', |
| 36 help='test the ICO file without modifying (set status ' |
| 37 'to 1 on error)') |
35 parser.add_argument('-d', '--debug', dest='debug', action='store_true', | 38 parser.add_argument('-d', '--debug', dest='debug', action='store_true', |
36 help='enable debug logging') | 39 help='enable debug logging') |
37 | 40 |
38 args = parser.parse_args() | 41 args = parser.parse_args() |
39 | 42 |
40 if args.debug: | 43 if args.debug: |
41 logging.getLogger().setLevel(logging.DEBUG) | 44 logging.getLogger().setLevel(logging.DEBUG) |
42 | 45 |
| 46 failed = False |
43 for file in args.files: | 47 for file in args.files: |
44 buf = StringIO.StringIO() | 48 buf = StringIO.StringIO() |
45 file.seek(0, os.SEEK_END) | 49 file.seek(0, os.SEEK_END) |
46 old_length = file.tell() | 50 old_length = file.tell() |
47 file.seek(0, os.SEEK_SET) | 51 file.seek(0, os.SEEK_SET) |
| 52 |
| 53 if args.lint: |
| 54 for error in ico_tools.LintIcoFile(file): |
| 55 logging.warning('%s: %s', file.name, error) |
| 56 # Any errors should cause this process to exit with a status of 1. |
| 57 failed = True |
| 58 continue |
| 59 |
48 ico_tools.OptimizeIcoFile(file, buf, args.optimization_level) | 60 ico_tools.OptimizeIcoFile(file, buf, args.optimization_level) |
49 | 61 |
50 new_length = len(buf.getvalue()) | 62 new_length = len(buf.getvalue()) |
51 | 63 |
52 # Always write (even if file size not reduced), because we make other fixes | 64 # Always write (even if file size not reduced), because we make other fixes |
53 # such as regenerating the AND mask. | 65 # such as regenerating the AND mask. |
54 file.truncate(new_length) | 66 file.truncate(new_length) |
55 file.seek(0) | 67 file.seek(0) |
56 file.write(buf.getvalue()) | 68 file.write(buf.getvalue()) |
57 | 69 |
58 if new_length >= old_length: | 70 if new_length >= old_length: |
59 logging.info('%s : Could not reduce file size.', file.name) | 71 logging.info('%s : Could not reduce file size.', file.name) |
60 else: | 72 else: |
61 saving = old_length - new_length | 73 saving = old_length - new_length |
62 saving_percent = float(saving) / old_length | 74 saving_percent = float(saving) / old_length |
63 logging.info('%s : %d => %d (%d bytes : %d %%)', file.name, old_length, | 75 logging.info('%s : %d => %d (%d bytes : %d %%)', file.name, old_length, |
64 new_length, saving, int(saving_percent * 100)) | 76 new_length, saving, int(saving_percent * 100)) |
65 | 77 |
| 78 return failed |
| 79 |
66 if __name__ == '__main__': | 80 if __name__ == '__main__': |
67 sys.exit(main()) | 81 sys.exit(main()) |
OLD | NEW |