Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(405)

Side by Side Diff: build/sanitize-png-files.sh

Issue 12095097: Introduces optimization level 1/2 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/bin/bash 1 #!/bin/bash
2 # Copyright (c) 2010 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2010 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 # The optimization code is based on pngslim (http://goo.gl/a0XHg) 6 # The optimization code is based on pngslim (http://goo.gl/a0XHg)
7 # and executes a similar pipleline to optimize the png file size. 7 # and executes a similar pipleline to optimize the png file size.
8 # The steps that require pngoptimizercl/pngrewrite/deflopt are omitted, 8 # The steps that require pngoptimizercl/pngrewrite/deflopt are omitted,
9 # but this runs all other processes, including: 9 # but this runs all other processes, including:
10 # 1) various color-dependent optimizations using optipng. 10 # 1) various color-dependent optimizations using optipng.
11 # 2) optimize the number of huffman blocks. 11 # 2) optimize the number of huffman blocks.
12 # 3) randomize the huffman table. 12 # 3) randomize the huffman table.
13 # 4) Further optimize using optipng and advdef (zlib stream). 13 # 4) Further optimize using optipng and advdef (zlib stream).
14 # Due to the step 3), each run may produce slightly different results. 14 # Due to the step 3), each run may produce slightly different results.
15 # 15 #
16 # Note(oshima): In my experiment, advdef didn't reduce much. I'm keeping it 16 # Note(oshima): In my experiment, advdef didn't reduce much. I'm keeping it
17 # for now as it does not take much time to run. 17 # for now as it does not take much time to run.
18 18
19 readonly ALL_DIRS=" 19 readonly ALL_DIRS="
20 ash/resources 20 ash/resources
21 ui/resources 21 ui/resources
22 chrome/app/theme 22 chrome/app/theme
23 chrome/browser/resources 23 chrome/browser/resources
24 chrome/renderer/resources 24 chrome/renderer/resources
25 webkit/glue/resources 25 webkit/glue/resources
26 remoting/resources 26 remoting/resources
27 remoting/webapp 27 remoting/webapp
28 " 28 "
29 29
30 # Files larger than this file size (in bytes) will
31 # use the optimization parameters tailored for large files.
32 LARGE_FILE_THRESHOLD=3000
33
30 # Constants used for optimization 34 # Constants used for optimization
31 readonly MIN_BLOCK_SIZE=128 35 readonly DEFAULT_MIN_BLOCK_SIZE=128
32 readonly LIMIT_BLOCKS=256 36 readonly DEFAULT_LIMIT_BLOCKS=256
33 readonly RANDOM_TRIALS=100 37 readonly DEFAULT_RANDOM_TRIALS=100
38 # Taken from the recommendation in the pngslim's readme.txt.
39 readonly LARGE_MIN_BLOCK_SIZE=1
40 readonly LARGE_LIMIT_BLOCKS=2
41 readonly LARGE_RANDOM_TRIALS=1
34 42
35 # Global variables for stats 43 # Global variables for stats
36 TOTAL_OLD_BYTES=0 44 TOTAL_OLD_BYTES=0
37 TOTAL_NEW_BYTES=0 45 TOTAL_NEW_BYTES=0
38 TOTAL_FILE=0 46 TOTAL_FILE=0
39 PROCESSED_FILE=0 47 PROCESSED_FILE=0
40 48
41 declare -a THROBBER_STR=('-' '\\' '|' '/') 49 declare -a THROBBER_STR=('-' '\\' '|' '/')
42 THROBBER_COUNT=0 50 THROBBER_COUNT=0
43 51
44 # Show throbber character at current cursor position. 52 # Show throbber character at current cursor position.
45 function throbber { 53 function throbber {
46 echo -ne "${THROBBER_STR[$THROBBER_COUNT]}\b" 54 echo -ne "${THROBBER_STR[$THROBBER_COUNT]}\b"
47 let THROBBER_COUNT=($THROBBER_COUNT+1)%4 55 let THROBBER_COUNT=($THROBBER_COUNT+1)%4
48 } 56 }
49 57
50 # Usage: pngout_loop <file> <png_out_options> ... 58 # Usage: pngout_loop <file> <png_out_options> ...
51 # Optimize the png file using pngout with the given options 59 # Optimize the png file using pngout with the given options
52 # using various block split thresholds and filter types. 60 # using various block split thresholds and filter types.
53 function pngout_loop { 61 function pngout_loop {
54 local file=$1 62 local file=$1
55 shift 63 shift
56 local opts=$* 64 local opts=$*
57 for i in 0 128 256 512; do 65 if [ $OPTIMIZE_LEVEL == 1 ]; then
58 for j in $(seq 0 5); do 66 for j in $(seq 0 5); do
59 throbber 67 throbber
60 pngout -q -k1 -s1 -b$i -f$j $opts $file 68 pngout -q -k1 -s1 -f$j $opts $file
61 done 69 done
62 done 70 else
71 for i in 0 128 256 512; do
72 for j in $(seq 0 5); do
73 throbber
74 pngout -q -k1 -s1 -b$i -f$j $opts $file
75 done
76 done
77 fi
78 }
79
80 # Usage: get_color_depth_list
81 # Returns the list of color depth options for current optimization level.
82 function get_color_depth_list {
83 if [ $OPTIMIZE_LEVEL == 1 ]; then
84 echo "-d0"
85 else
86 echo "-d1 -d2 -d4 -d8"
87 fi
63 } 88 }
64 89
65 # Usage: process_grayscale <file> 90 # Usage: process_grayscale <file>
66 # Optimize grayscale images for all color bit depths. 91 # Optimize grayscale images for all color bit depths.
67 # 92 #
68 # TODO(oshima): Experiment with -d0 w/o -c0. 93 # TODO(oshima): Experiment with -d0 w/o -c0.
69 function process_grayscale { 94 function process_grayscale {
70 echo -n "|gray" 95 echo -n "|gray"
71 for opt in -d1 -d2 -d4 -d8; do 96 for opt in $(get_color_depth_list); do
72 pngout_loop $file -c0 $opt 97 pngout_loop $file -c0 $opt
73 done 98 done
74 } 99 }
75 100
76 # Usage: process_grayscale_alpha <file> 101 # Usage: process_grayscale_alpha <file>
77 # Optimize grayscale images with alpha for all color bit depths. 102 # Optimize grayscale images with alpha for all color bit depths.
78 function process_grayscale_alpha { 103 function process_grayscale_alpha {
79 echo -n "|gray-a" 104 echo -n "|gray-a"
80 pngout_loop $file -c4 105 pngout_loop $file -c4
81 for opt in -d1 -d2 -d4 -d8; do 106 for opt in $(get_color_depth_list); do
82 pngout_loop $file -c3 $opt 107 pngout_loop $file -c3 $opt
83 done 108 done
84 } 109 }
85 110
86 # Usage: process_rgb <file> 111 # Usage: process_rgb <file>
87 # Optimize rgb images with or without alpha for all color bit depths. 112 # Optimize rgb images with or without alpha for all color bit depths.
88 function process_rgb { 113 function process_rgb {
89 echo -n "|rgb" 114 echo -n "|rgb"
90 for opt in -d1 -d2 -d4 -d8; do 115 for opt in $(get_color_depth_list); do
91 pngout_loop $file -c3 $opt 116 pngout_loop $file -c3 $opt
92 done 117 done
93 pngout_loop $file -c2 118 pngout_loop $file -c2
94 pngout_loop $file -c6 119 pngout_loop $file -c6
95 } 120 }
96 121
97 # Usage: huffman_blocks <file> 122 # Usage: huffman_blocks <file>
98 # Optimize the huffman blocks. 123 # Optimize the huffman blocks.
99 function huffman_blocks { 124 function huffman_blocks {
100 local file=$1 125 local file=$1
101 echo -n "|huffman" 126 echo -n "|huffman"
102 local size=$(stat -c%s $file) 127 local size=$(stat -c%s $file)
103 let MAX_BLOCKS=$size/$MIN_BLOCK_SIZE 128 local min_block_size=$DEFAULT_MIN_BLOCK_SIZE
104 if [ $MAX_BLOCKS -gt $LIMIT_BLOCKS ]; then 129 local limit_blocks=$DEFAULT_LIMIT_BLOCKS
105 MAX_BLOCKS=$LIMIT_BLOCKS 130
131 if [ $size -gt $LARGE_FILE_THRESHOLD ]; then
132 min_block_size=$LARGE_MIN_BLOCK_SIZE
133 limit_blocks=$LARGE_LIMIT_BLOCKS
106 fi 134 fi
107 for i in $(seq 2 $MAX_BLOCKS); do 135 let max_blocks=$size/$min_block_size
136 if [ $max_blocks -gt $limit_blocks ]; then
137 max_blocks=$limit_blocks
138 fi
139
140 for i in $(seq 2 $max_blocks); do
108 throbber 141 throbber
109 pngout -q -k1 -ks -s1 -n$i $file 142 pngout -q -k1 -ks -s1 -n$i $file
110 done 143 done
111 } 144 }
112 145
113 # Usage: random_huffman_table_trial <file> 146 # Usage: random_huffman_table_trial <file>
114 # Try compressing by randomizing the initial huffman table. 147 # Try compressing by randomizing the initial huffman table.
115 # 148 #
116 # TODO(oshima): Try adjusting different parameters for large files to 149 # TODO(oshima): Try adjusting different parameters for large files to
117 # reduce runtime. 150 # reduce runtime.
118 function random_huffman_table_trial { 151 function random_huffman_table_trial {
119 echo -n "|random" 152 echo -n "|random"
120 local file=$1 153 local file=$1
121 local old_size=$(stat -c%s $file) 154 local old_size=$(stat -c%s $file)
122 for i in $(seq 1 $RANDOM_TRIALS); do 155 local trials_count=$DEFAULT_RANDOM_TRIALS
156
157 if [ $old_size -gt $LARGE_FILE_THRESHOLD ]; then
158 trials_count=$LARGE_RANDOM_TRIALS
159 fi
160 for i in $(seq 1 $trials_count); do
123 throbber 161 throbber
124 pngout -q -k1 -ks -s0 -r $file 162 pngout -q -k1 -ks -s0 -r $file
125 done 163 done
126 local new_size=$(stat -c%s $file) 164 local new_size=$(stat -c%s $file)
127 if [ $new_size -lt $old_size ]; then 165 if [ $new_size -lt $old_size ]; then
128 random_huffman_table_trial $file 166 random_huffman_table_trial $file
129 fi 167 fi
130 } 168 }
131 169
132 # Usage: final_comprssion <file> 170 # Usage: final_comprssion <file>
133 # Further compress using optipng and advdef. 171 # Further compress using optipng and advdef.
134 # TODO(oshima): Experiment with 256. 172 # TODO(oshima): Experiment with 256.
135 function final_compression { 173 function final_compression {
136 echo -n "|final" 174 echo -n "|final"
137 local file=$1 175 local file=$1
138 for i in 32k 16k 8k 4k 2k 1k 512; do 176 if [ $OPTIMIZE_LEVEL == 2 ]; then
139 throbber 177 for i in 32k 16k 8k 4k 2k 1k 512; do
140 optipng -q -nb -nc -zw$i -zc1-9 -zm1-9 -zs0-3 -f0-5 $file 178 throbber
141 done 179 optipng -q -nb -nc -zw$i -zc1-9 -zm1-9 -zs0-3 -f0-5 $file
180 done
181 fi
142 for i in $(seq 1 4); do 182 for i in $(seq 1 4); do
143 throbber 183 throbber
144 advdef -q -z -$i $file 184 advdef -q -z -$i $file
145 done 185 done
146 echo -ne "\r" 186 echo -ne "\r"
147 } 187 }
148 188
149 # Usage: optimize_size <file> 189 # Usage: optimize_size <file>
150 # Performs png file optimization. 190 # Performs png file optimization.
151 function optimize_size { 191 function optimize_size {
(...skipping 19 matching lines...) Expand all
171 fi 211 fi
172 212
173 echo -n "|filter" 213 echo -n "|filter"
174 optipng -q -zc9 -zm8 -zs0-3 -f0-5 $file 214 optipng -q -zc9 -zm8 -zs0-3 -f0-5 $file
175 pngout -q -k1 -s1 $file 215 pngout -q -k1 -s1 $file
176 216
177 huffman_blocks $file 217 huffman_blocks $file
178 218
179 # TODO(oshima): Experiment with strategy 1. 219 # TODO(oshima): Experiment with strategy 1.
180 echo -n "|strategy" 220 echo -n "|strategy"
181 for i in 3 2 0; do 221 if [ $OPTIMIZE_LEVEL == 2 ]; then
182 pngout -q -k1 -ks -s$i $file 222 for i in 3 2 0; do
183 done 223 pngout -q -k1 -ks -s$i $file
224 done
225 else
226 pngout -q -k1 -ks -s1 $file
227 fi
184 228
185 random_huffman_table_trial $file 229 if [ $OPTIMIZE_LEVEL == 2 ]; then
230 random_huffman_table_trial $file
231 fi
186 232
187 final_compression $file 233 final_compression $file
188 } 234 }
189 235
190 # Usage: process_file <file> 236 # Usage: process_file <file>
191 function process_file { 237 function process_file {
192 local file=$1 238 local file=$1
193 local name=$(basename $file) 239 local name=$(basename $file)
194 # -rem alla removes all ancillary chunks except for tRNS 240 # -rem alla removes all ancillary chunks except for tRNS
195 pngcrush -d $TMP_DIR -brute -reduce -rem alla $file > /dev/null 241 pngcrush -d $TMP_DIR -brute -reduce -rem alla $file > /dev/null
196 242
197 if [ ! -z "$OPTIMIZE" ]; then 243 if [ $OPTIMIZE_LEVEL != 0 ]; then
198 optimize_size $TMP_DIR/$name 244 optimize_size $TMP_DIR/$name
199 fi 245 fi
200 } 246 }
201 247
202 # Usage: sanitize_file <file> 248 # Usage: sanitize_file <file>
203 function sanitize_file { 249 function sanitize_file {
204 local file=$1 250 local file=$1
205 local name=$(basename $file) 251 local name=$(basename $file)
206 local old=$(stat -c%s $file) 252 local old=$(stat -c%s $file)
207 local tmp_file=$TMP_DIR/$name 253 local tmp_file=$TMP_DIR/$name
208 254
209 process_file $file 255 process_file $file
210 256
211 local new=$(stat -c%s $tmp_file) 257 local new=$(stat -c%s $tmp_file)
212 let diff=$old-$new 258 let diff=$old-$new
213 let TOTAL_OLD_BYTES+=$old
214 let TOTAL_NEW_BYTES+=$new
215 let percent=($diff*100)/$old 259 let percent=($diff*100)/$old
216 let TOTAL_FILE+=1 260 let TOTAL_FILE+=1
217 261
218 tput el 262 tput el
219 if [ $new -lt $old ]; then 263 if [ $new -lt $old ]; then
220 echo -ne "$file : $old => $new ($diff bytes : $percent %)\n" 264 echo -ne "$file : $old => $new ($diff bytes : $percent %)\n"
221 mv "$tmp_file" "$file" 265 mv "$tmp_file" "$file"
266 let TOTAL_OLD_BYTES+=$old
267 let TOTAL_NEW_BYTES+=$new
222 let PROCESSED_FILE+=1 268 let PROCESSED_FILE+=1
223 else 269 else
224 if [ -z "$OPTIMIZE" ]; then 270 if [ $OPTIMIZE_LEVEL == 0 ]; then
225 echo -ne "$file : skipped\r" 271 echo -ne "$file : skipped\r"
226 fi 272 fi
227 rm $tmp_file 273 rm $tmp_file
228 fi 274 fi
229 } 275 }
230 276
231 function sanitize_dir { 277 function sanitize_dir {
232 local dir=$1 278 local dir=$1
233 for f in $(find $dir -name "*.png"); do 279 for f in $(find $dir -name "*.png"); do
234 sanitize_file $f 280 sanitize_file $f
(...skipping 22 matching lines...) Expand all
257 303
258 function show_help { 304 function show_help {
259 local program=$(basename $0) 305 local program=$(basename $0)
260 echo \ 306 echo \
261 "Usage: $program [options] dir ... 307 "Usage: $program [options] dir ...
262 308
263 $program is a utility to reduce the size of png files by removing 309 $program is a utility to reduce the size of png files by removing
264 unnecessary chunks and compressing the image. 310 unnecessary chunks and compressing the image.
265 311
266 Options: 312 Options:
267 -o Aggressively optimize file size. Warning: this is *VERY* slow and 313 -o<optimize_level> Specify optimization level: (default is 1)
268 can take hours to process all files. 314 0 Just run pngcrush. It removes unnecessary chunks and perform basic
315 optimization on the encoded data.
316 1 Optimize png files using pngout/optipng and advdef. This can further
317 reduce addtional 5~30%. This is the default level.
318 2 Aggressively optimize the size of png files. This may produce
319 addtional 1%~5% reduction. Warning: this is *VERY*
320 slow and can take hours to process all files.
269 -h Print this help text." 321 -h Print this help text."
270 exit 1 322 exit 1
271 } 323 }
272 324
273 if [ ! -e ../.gclient ]; then 325 if [ ! -e ../.gclient ]; then
274 echo "$0 must be run in src directory" 326 echo "$0 must be run in src directory"
275 exit 1 327 exit 1
276 fi 328 fi
277 329
330 OPTIMIZE_LEVEL=1
278 # Parse options 331 # Parse options
279 while getopts oh opts 332 while getopts o:h opts
280 do 333 do
281 case $opts in 334 case $opts in
282 o) 335 o)
283 OPTIMIZE=true; 336 if [[ ! "$OPTARG" =~ [012] ]]; then
337 show_help
338 fi
339 OPTIMIZE_LEVEL=$OPTARG
340 [ "$1" == "-o" ] && shift
284 shift;; 341 shift;;
285 [h?]) 342 [h?])
286 show_help;; 343 show_help;;
287 esac 344 esac
288 done 345 done
289 346
290 # Make sure we have all necessary commands installed. 347 # Make sure we have all necessary commands installed.
291 install_if_not_installed pngcrush 348 install_if_not_installed pngcrush
292 if [ ! -z "$OPTIMIZE" ]; then 349 if [ $OPTIMIZE_LEVEL != 2 ]; then
293 install_if_not_installed optipng 350 install_if_not_installed optipng
294 fail_if_not_installed advdef "http://advancemame.sourceforge.net/comp-download .html" 351 fail_if_not_installed advdef "http://advancemame.sourceforge.net/comp-download .html"
295 fail_if_not_installed pngout "http://www.jonof.id.au/kenutils" 352 fail_if_not_installed pngout "http://www.jonof.id.au/kenutils"
296 fi 353 fi
297 354
298 # Create tmp directory for crushed png file. 355 # Create tmp directory for crushed png file.
299 TMP_DIR=$(mktemp -d) 356 TMP_DIR=$(mktemp -d)
300 357
301 # Make sure we cleanup temp dir 358 # Make sure we cleanup temp dir
302 trap "rm -rf $TMP_DIR" EXIT 359 trap "rm -rf $TMP_DIR" EXIT
303 360
304 # If no directories are specified, sanitize all directories. 361 # If no directories are specified, sanitize all directories.
305 DIRS=$@ 362 DIRS=$@
306 set ${DIRS:=$ALL_DIRS} 363 set ${DIRS:=$ALL_DIRS}
307 364
365 echo "Optimize level=$OPTIMIZE_LEVEL"
308 for d in $DIRS; do 366 for d in $DIRS; do
309 echo "Sanitizing png files in $d" 367 echo "Sanitizing png files in $d"
310 sanitize_dir $d 368 sanitize_dir $d
311 echo 369 echo
312 done 370 done
313 371
314 # Print the results. 372 # Print the results.
315 let diff=$TOTAL_OLD_BYTES-$TOTAL_NEW_BYTES 373 let diff=$TOTAL_OLD_BYTES-$TOTAL_NEW_BYTES
316 let percent=$diff*100/$TOTAL_OLD_BYTES 374 let percent=$diff*100/$TOTAL_OLD_BYTES
317 echo "Processed $PROCESSED_FILE files (out of $TOTAL_FILE files)" \ 375 echo "Processed $PROCESSED_FILE files (out of $TOTAL_FILE files)" \
318 "in $(date -u -d @$SECONDS +%T)s" 376 "in $(date -u -d @$SECONDS +%T)s"
319 echo "Result : $TOTAL_OLD_BYTES => $TOTAL_NEW_BYTES bytes" \ 377 echo "Result : $TOTAL_OLD_BYTES => $TOTAL_NEW_BYTES bytes" \
320 "($diff bytes : $percent %)" 378 "($diff bytes : $percent %)"
321 379
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698