- # This is slow, but should fortunately almost never happen, so don't bother
- # special-casing it.
- if (!defined($dbwidth) || !defined($dbheight)) {
- my $img = read_original_image($r, $filename, $id, $dbwidth, $dbheight, 0);
- $new_dbwidth = $width = $img->Get('columns');
- $new_dbheight = $height = $img->Get('rows');
+ if ($format eq 'jpg') {
+ my %parms = (
+ filename => $cachename,
+ quality => $quality
+ );
+ if (($nwidth >= 640 && $nheight >= 480) ||
+ ($nwidth >= 480 && $nheight >= 640)) {
+ $parms{'interlace'} = 'Plane';
+ }
+ if (defined($sf)) {
+ $parms{'sampling-factor'} = $sf;
+ }
+ $err = $cimg->write(%parms);
+ } elsif ($format eq 'avif') {
+ # ImageMagick doesn't have AVIF support until version 7,
+ # and Debian hasn't packaged that even in unstable as of 2021.
+ # So we'll need to do it the manual way. (We don't use /tmp, for security reasons.)
+ (my $dirname = $cachename) =~ s,/[^/]*$,,;
+ my ($fh, $raw_filename) = File::Temp::tempfile('tmp.XXXXXXXX', DIR => $dirname, SUFFIX => '.ycbcr');
+ # Write a Y4M header, so that we get the chroma range correct.
+ printf $fh "YUV4MPEG2 W%d H%d F25:1 Ip A1:1 C444 XYSCSS=444 XCOLORRANGE=FULL\nFRAME\n", $nwidth, $nheight;
+ my %parms = (
+ file => $fh,
+ filename => $raw_filename,
+ interlace => 'Plane'
+ );
+ $cimg->write(%parms);
+ close($fh);
+ my $ivf_filename;
+ ($fh, $ivf_filename) = File::Temp::tempfile('tmp.XXXXXXXX', DIR => $dirname, SUFFIX => '.ivf');
+ close($fh);
+ system('aomenc', '--quiet', '--cpu-used=0', '--bit-depth=10', '--end-usage=q', '--cq-level=13', '--target-bitrate=0', '--good', '--aq-mode=1', '--matrix-coefficients=bt601', '-o', $ivf_filename, $raw_filename);
+ unlink($raw_filename);
+ system('MP4Box', '-quiet', '-add-image', "$ivf_filename:primary", '-ab', 'avif', '-ab', 'miaf', '-new', $cachename);
+ unlink($ivf_filename);
+ } elsif ($format eq 'jxl') {
+ # Similar, for JPEG-XL.
+ (my $dirname = $cachename) =~ s,/[^/]*$,,;
+ my ($fh, $raw_filename) = File::Temp::tempfile('tmp.XXXXXXXX', DIR => $dirname, SUFFIX => '.ppm');
+ my %parms = (
+ file => $fh,
+ filename => $raw_filename
+ );
+ $cimg->write(%parms);
+ close($fh);
+ system('cjxl', '-p', $raw_filename, $cachename);
+ unlink($raw_filename);