Good day!

I have a script that runs from CMD like this:

perl jpegrescan.pl jpegtran image.jpg image.jpg 

Jpegrescan.pl has a line

 die "File $fin is not RGB or grayscale\n" 

Tell me how to make the image process with the following parameters occur when this condition occurs:

 jpegtran -copy all -progressive image.jpg image.jpg 

Actually jpegrescan.pl

 #!/usr/bin/perl -ws # jpegrescan by Loren Merritt # Last updated: 2008-11-29 / Andrey Chernomyrdin 2012-04-28 # This code is public domain. sub jpegtran (@) { unless(system($ARGV[0], $strip ? ("-copy","none") : ("-copy","all"), @_ ) == 0) { if ($? == -1) { die "Error execute jpegtran: $!\n"; } elsif ($? & 128) { die sprintf( "jpegtran died with signal %d, %s coredump\n", ($? & 127), ($? & 128) ? 'with' : 'without' ); } else { die "jpegtran exited with ERRORLEVEL=" . $? >> 8 . "\n"; } } } # FIXME optimize order for either progressive transfer or decoding speed sub canonize { my $txt = $prefix.$suffix.shift; $txt =~ s/\s*;\s*/;\n/g; $txt =~ s/^\s*//; $txt =~ s/ +/ /g; $txt =~ s/: (\d+) (\d+)/sprintf ": %2d %2d", $1, $2/ge; # treat u and v identically. I shouldn't need to do this, but with jpegtran overhead it saves 9% speed. cost: .008% bitrate. $txt =~ s/^2:.*\n//gm; $txt =~ s/^1:(.+)\n/1:$1\n2:$1\n/gm; # dc before ac, coarse before fine return join( "\n", sort { "$a\n$b" =~ /: *(\d+) .* (\d);\n.*: *(\d+) .* (\d);/ or die; !$3 <=> !$1 or $4 <=> $2 or $a cmp $b; } split( /\n/, $txt ) ); } sub try { my $txt = canonize(shift); my $rc; # print $txt, "\n\n"; # debug if (exists $memo{$txt}) { $rc = $memo{$txt}; } else { open( my $io, "> $ftmp") or die "Error create $ftmp file: $!\n"; print $io $txt; close $io; unlink $fout if (-f $fout); jpegtran("-scans", $ftmp, "-outfile", $fout, $jtmp); unless ($rc = -s $fout) { die "jpegtran output file zero size"; } unless ($quiet) { print $verbose ? "$txt\n$rc\n\n" : "."; } $memo{$txt} = $rc; } return $rc; } sub triesn { my ($limit, @modes) = @_ ; my $overshoot = 0; my ($bmode, $bsize); foreach my $mode (@modes) { my $s = try($mode); if (!$bsize || $s < $bsize) { $bsize = $s; $bmode = $mode; $overshoot = 0; } elsif ($limit > 0 and ++$overshoot >= $limit) { last; } } return $bmode; } sub gen_modes { my $c = shift; my $str = shift; map { $_ => sprintf( "$c: 1 %d $str;$c: %d 63 $str;", $_, $_+1) } 2,5,8,12,18; } sub try_splits { my $c = shift; my $str = shift; my %n = gen_modes($c, $str); my $mode = triesn(2, "$c: 1 63 $str;", @n {2,8,5}); if ($mode ne $n{8}) { return $mode; } else { return triesn(1, $mode, @n {12,18}); } } sub get_stderr { my $code = shift; my $rc; if (ref $code eq 'CODE') { my $old_stderr; open $old_stderr, ">&", STDERR; open STDERR, ">", $otmp; $code->( @_ ); open STDERR, ">&", $old_stderr; $rc = do { local $/; open(my $io, $otmp); <$io>; }; unlink( $otmp ) if (-f $otmp); } return $rc; } # sub main { unless (scalar @ARGV == 3) { die "usage: jpegrescan /path/to/jpegtran.exe in.jpg out.jpg\ntries various progressive scan orders\n"; } $fin = $ARGV[1]; $fout = $ARGV[2]; $verbose = 0; $quiet = 0; $strip = 0; $ftmp = "$fout-$$.scan"; $jtmp = "$fout-$$.jpg"; $otmp = "$fout-$$.out"; undef $/; $|=1; $prefix = ""; $suffix = ""; # convert the input to baseline, just to make all the other conversions faster # FIXME there's still a bunch of redundant computation in separate calls to jpegtran my $stderr = get_stderr( sub { jpegtran("-v", "-optimize", "-outfile", $jtmp, $fin); } ); if ($stderr =~ /components=(\d+)/) { my $rgb; if ($1 == 3) { $rgb = 1; # 012 helps very little # 0/12 and 0/1/2 are pretty evenly matched in frequency, but 0/12 wins in total size if every image had to use the same mode # dc refinement passes never help $dc = triesn(0, "0: 0 0 0 0;1: 0 0 0 0;2: 0 0 0 0;" ); # jpegtran won't let me omit dc entirely, but I can at least quantize it away to make the rest of the tests faster. $prefix = "0 1 2: 0 0 0 9;"; } elsif ($1 == 1) { $rgb = 0; $dc = "0: 0 0 0 0;"; $prefix = "0: 0 0 0 9;"; } else { die "File $fin is not RGB or grayscale\n" } foreach my $c ( 0 .. $rgb ) { my $max_i = $c ? 2 : 3; my $ml = ""; my @modes; my $refine; foreach my $i ( 0 .. $max_i ) { push @modes, "$c: 1 8 0 $i;$c: 9 63 0 $i;".$ml; $ml .= sprintf("$c: 1 63 %d %d;", $i+1, $i); } $refine = triesn(1, @modes); $refine =~ s/.* (0 \d);//; $ac .= $refine . try_splits($c, $1); } # luma can make use of up to 3 refinement passes. # chroma can make use of up to 2 refinement passes. # refinement passes have some chance of being split (luma: 4%,4%,4%. chroma: 20%,8%) but the total bit gain is negligible. # msb pass should almost always be split (luma: 87%, chroma: 81%). # I have no theoretical reason for this list of split positions, they're just the most common in practice. # splitting into 3 ections is often slightly better, but the total number of bits saved is negligible. # FIXME: penalize lots of refinement passes because it's slower to decode. if so, then also force overwrite if bigger than the input. $prefix = ""; %memo = (); $mode = $dc.$ac; $mode = canonize($mode); try($mode); $size = $memo{$mode}; print "\n$mode\n$size\n" unless ($quiet); unlink( $jtmp, $ftmp, ); } else { die "Invalud output from jpegtran\n"; } 
  • Need to change jpegrescan.pl or the script that calls it? - zb '

2 answers 2

Uh ... I didn’t quite understand what the problem was to replace die with a jpegtran call with the necessary parameters?

 jpegtran("-progressive", $fin, $fout); 

Parsing stderr already to taste.

  • The fact is, I don't know perl at all. did as you said, Perl issues: Use of uninitialized value $ rgb in foreach loop entry at C: \ Users \ Lorents \ Desktop \ Image Catalyst \ Tools \ scripts \ jpegrescan.pl line 170. In Invalid progressive parameters at scan script entry 1 Argument "jpegtran exited with ERRORLEVEL = 256" isn’t numeric at right bitshift (>>) at C: \ Users \ Lorents \ Desktop \ Image Catalyst \ Tools \ scripts \ jpegrescan.pl line 18. 0 at C: \ Users \ Lorents \ Desktop \ Image Catalyst \ Tools \ scripts \ jpegrescan.pl line 18. - lorents
  • Since $ rgb is clear: just in this else, where die was called, the value of this variable is really undefined. Insert $ rgb = what_is needed; before calling jpegtran (). I will not suggest more, sorry, debugging and editing other people's sources is work. And if it is perl and without use strict, then with a surcharge for harm :) - user6550
  • Thank! I will understand jpegrescan.pl is used in my project forum.ru-board.com/topic.cgi?forum=4&topic=4263 The project is completely free, but now I have time to finalize it on the sly. - lorents

Don't you think that

 die "File $fin is not RGB or grayscale\n" 

not just because This means that the color model of jpeg, not RGB or shades of gray, but for example LAB or anything else (where the program crashes - die). And for this color model, this algorithm is not provided.

  • The fact is that jpegtran itself perfectly supports all kinds of jpeg. jpegrescan.pl is, in fact, some add-on over jpegtran, while jpegrescan.pl only supports RGB and grayscale, but does not support CMYK. But jpegtran itself supports CMYK, for this reason I want to remove this restriction. - lorents 2:44 pm