chiark / gitweb /
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 fc937729bb7cd5de46db403b2295444729505b1f..d6d3afb4ce32fa90f5c2e9a235764937c707bc2d 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);