@@ -118,6 +118,7 @@ int save_jfif = 1;
118118int strip_none = 0 ;
119119double threshold = -1.0 ;
120120int csv = 0 ;
121+ int auto_mode = 0 ;
121122int all_normal = 0 ;
122123int all_progressive = 0 ;
123124int target_size = 0 ;
@@ -143,6 +144,7 @@ const struct option long_options[] = {
143144 { "all-arith" , 0 , & arith_mode , 1 },
144145 { "all-huffman" , 0 , & arith_mode , 0 },
145146#endif
147+ { "auto-mode" , 0 , & auto_mode , 1 },
146148 { "all-normal" , 0 , & all_normal , 1 },
147149 { "all-progressive" , 0 , & all_progressive , 1 },
148150 { "csv" , 0 , 0 , 'b' },
@@ -297,6 +299,8 @@ void print_usage(void)
297299 "\n"
298300 " --all-normal force all output files to be non-progressive\n"
299301 " --all-progressive force all output files to be progressive\n"
302+ " --auto-mode select normal or progressive based on which produces\n"
303+ " smaller output file\n"
300304#ifdef HAVE_ARITH_CODE
301305 " --all-arith force all output files to use arithmetic coding\n"
302306 " --all-huffman force all output files to use Huffman coding\n"
@@ -505,15 +509,14 @@ void parse_arguments(int argc, char **argv, char *dest_path, size_t dest_path_le
505509
506510 if (stdin_mode )
507511 stdout_mode = 1 ;
508-
509- if (all_normal && all_progressive )
510- fatal ("cannot specify both --all-normal and --all-progressive" );
511-
512512 if (files_stdin )
513513 files_from = stdin ;
514-
515514 if (stdin_mode && files_from == stdin )
516515 fatal ("cannot specify both --stdin and --files-stdin" );
516+ if (all_normal && all_progressive )
517+ fatal ("cannot specify both --all-normal and --all-progressive" );
518+ if (auto_mode && (all_normal || all_progressive ))
519+ fatal ("cannot specify --all-normal or --all-progressive if using --auto-mode" );
517520}
518521
519522
@@ -1032,34 +1035,72 @@ int optimize(FILE *log_fh, const char *filename, const char *newname,
10321035 jpeg_finish_decompress (& dinfo );
10331036 free_line_buf (& buf , dinfo .output_height );
10341037
1035- if (retry_mode && retry != 1 && quality >= 0 && outsize <= insize ) {
1036- /* Retry compression until output file stops getting smaller
1037- or we hit max limit of iterations (10)... */
1038- if (retry_count == 0 )
1039- last_retry_size = outsize + 1 ;
1040- if (++ retry_count < 10 && outsize < last_retry_size ) {
1038+ if (retry_mode ) {
1039+ if ((retry == 0 || retry == 2 ) && quality >= 0 && outsize <= insize ) {
1040+ /* Retry compression until output file stops getting smaller
1041+ or we hit max limit of iterations (10)... */
1042+ if (retry_count == 0 )
1043+ last_retry_size = outsize + 1 ;
1044+ if (++ retry_count < 10 && outsize < last_retry_size ) {
1045+ if (tmpbuffer )
1046+ free (tmpbuffer );
1047+ tmpbuffer = outbuffer ;
1048+ tmpbuffersize = outbuffersize ;
1049+ outbuffer = NULL ;
1050+ last_retry_size = outsize ;
1051+ retry = 2 ;
1052+ if (verbose_mode )
1053+ fprintf (log_fh , "(retry%d: %lu) " , retry_count , outsize );
1054+ goto retry_point ;
1055+ }
1056+ }
1057+ if (retry == 2 ) {
1058+ if (verbose_mode )
1059+ fprintf (log_fh , "(retry done: %lu) " , outsize );
1060+ if (outsize > last_retry_size ) {
1061+ if (outbuffer )
1062+ free (outbuffer );
1063+ outbuffer = tmpbuffer ;
1064+ outbuffersize = tmpbuffersize ;
1065+ outsize = outbuffersize + extrabuffersize ;
1066+ tmpbuffer = NULL ;
1067+ }
1068+ }
1069+ }
1070+
1071+ /* If auto_mode, try both progressive and non-progressive... */
1072+ if (auto_mode ) {
1073+ int newmode = (dinfo .progressive_mode ? 0 : 1 );
1074+ if (retry != 3 ) {
1075+ if (newmode )
1076+ all_progressive = 1 ;
1077+ else
1078+ all_normal = 1 ;
10411079 if (tmpbuffer )
10421080 free (tmpbuffer );
10431081 tmpbuffer = outbuffer ;
10441082 tmpbuffersize = outbuffersize ;
10451083 outbuffer = NULL ;
10461084 last_retry_size = outsize ;
1047- retry = 2 ;
1085+ retry = 3 ;
10481086 if (verbose_mode )
1049- fprintf (log_fh , "(retry%d: %lu ) " , retry_count , outsize );
1087+ fprintf (log_fh , "(retry w/%s ) " , ( newmode ? "progressive" : "normal" ) );
10501088 goto retry_point ;
1051- }
1052- }
1053- if (retry == 2 ) {
1054- if (verbose_mode )
1055- fprintf (log_fh , "(retry done: %lu) " , outsize );
1056- if (outsize > last_retry_size ) {
1057- if (outbuffer )
1058- free (outbuffer );
1059- outbuffer = tmpbuffer ;
1060- outbuffersize = tmpbuffersize ;
1061- outsize = outbuffersize + extrabuffersize ;
1062- tmpbuffer = NULL ;
1089+ } else {
1090+ if (verbose_mode > 1 )
1091+ fprintf (log_fh , "(automode done: %lu) " , outsize );
1092+ if (outsize > last_retry_size ) {
1093+ if (verbose_mode )
1094+ fprintf (log_fh , "(revert to %s) " , (!newmode ? "progressive" : "normal" ));
1095+ all_progressive = 0 ;
1096+ all_normal = 0 ;
1097+ if (outbuffer )
1098+ free (outbuffer );
1099+ outbuffer = tmpbuffer ;
1100+ outbuffersize = tmpbuffersize ;
1101+ outsize = outbuffersize + extrabuffersize ;
1102+ tmpbuffer = NULL ;
1103+ }
10631104 }
10641105 }
10651106
0 commit comments