mason/.perl-lib/TrivGal.pm (Image): Use `Image::Size' to find image size.
authorMark Wooding <mdw@distorted.org.uk>
Tue, 20 Jun 2023 20:09:32 +0000 (21:09 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Wed, 21 Jun 2023 09:17:54 +0000 (10:17 +0100)
Using `Image::Imlib2' means that we don't learn the size without fully
decoding the image and using up lots of memory.  The `Image::Size'
package will determine the image size by reading it out of the file
without decoding, so it's much faster.

Of course, that doesn't matter much yet, because we're only using it
/after/ we decode the image.  Hmm...

mason/.perl-lib/TrivGal.pm

index fc93772..d6d3afb 100644 (file)
@@ -32,6 +32,7 @@ use Exporter qw{import};
 use File::stat;
 use Image::ExifTool qw{};
 use Image::Imlib2;
+use Image::Size qw{};
 use User::pwent;
 use POSIX;
 
@@ -215,10 +216,24 @@ package TrivGal::Image {
     return bless {
       path => $path, imgpath => $imgpath,
       mtime => $st->mtime,
-      img => undef
+      img => undef,
+      _wd => undef, _ht => undef,
+      sz => undef
     }, $cls;
   }
 
+  sub _getsz ($) {
+    my ($me) = @_;
+    return if defined $me->{_wd};
+
+    my ($wd, $ht, $err) = Image::Size::imgsize $me->{imgpath};
+    defined $wd or die "failed to read size of `$me->{path}': $err";
+    my $sz = $wd; if ($sz < $ht) { $sz = $ht; }
+    @$me{"_wd", "_ht", "sz"} = ($wd, $ht, $sz);
+  }
+
+  sub sz ($) { my ($me) = @_; $me->_getsz; return $me->{sz}; }
+
   sub scale ($$;$) {
     my ($me, $scale, $forcep) = @_;
     my $m = HTML::Mason::Request->instance;
@@ -250,11 +265,9 @@ package TrivGal::Image {
       }
     }
 
-    my ($wd, $ht) = ($img->width, $img->height);
-    my $max = $wd > $ht ? $wd : $ht;
-    if ($max <= $sz)
+    if ($me->sz <= $sz)
       { return $m->interp->apply_escapes("$IMGURL/$path", "u"); }
-    my $sc = $sz/$max;
+    my $sc = $sz/$me->sz;
     my $scaled = $img->create_scaled_image($sc*$wd, $sc*$ht);
 
     $scaled->image_set_format($ty->imlibfmt);