MonkDrew has asked for the wisdom of the Perl Monks concerning the following question:

I basically have an HTTP server that serves out hundreds of requests per second, and I want to attempt to gzip the images it serves (they are cached in memory). The only solution I can find for this involves specifying a buffer which the module will then gzip automatically. This doesn't work for my setup. Is there a way to have a variable, say $image_one, and gzip (inflate) its contents?

Replies are listed 'Best First'.
Re: Gzip inflate a variable
by rkrieger (Friar) on Jan 21, 2010 at 22:33 UTC

    You use 'inflate', whereas I believe the gzip man page mentions 'deflate' for the compression mode. Did I misunderstand? I suspect compress/deflate is analogous to making a balloon smaller by deflating it.

    Assuming you want to send out content in gzip'ed form and the images are static, you may want to place them in a separate directory, serve them from a lightweight process (thttpd, nginx, or a lean apache) or behind a proxy server (squid, varnish, pound, whichever you prefer). Granted, that's a non-programming solution which may not fit your case.

    For storing gzip'ed data, I suppose IO::Compress::Gzip would allow you to gzip() to store to a scalar reference.

    Shamelessly stolen from the synopsis and altered off-the-cuff:

    use IO::Compress::Gzip qw(gzip $GzipError); my $gzip_data; my $status = gzip $input => \$gzip_data [,OPTS] or die "gzip failed: $GzipError\n";

    Would this be what you're looking for? I suppose it's not too difficult to send out $gzip_data to a HTTP client end of the Perl code. Or did I simply mistake what you're trying to do?

      Yeah, you are right... sorry. Your analogy makes sense now. Basically my perl script is the entire HTTP server, so it handles accessing the filesystem and caching. So I guess using your example I can have the contents of the image in variable $foo. Then do:
      use IO::Compress::Gzip qw(gzip $GzipError); my $compressed; if(gzip $foo => \$compressed [,OPTS]){ # Compressed version of $foo stored in $compressed }
        That's not quite correct. To read from a variable and write to a variable you need to add a backslash to both the input & output variables
        use IO::Compress::Gzip qw(gzip $GzipError); my $compressed; if(gzip \$foo => \$compressed [,OPTS]){ # Compressed version of $foo stored in $compressed }
        If you want the output to go to a filehandle
        # assume $fh is a filehandle ... gzip \$foo => $fh
        If you want to send the output to standard output, use "-"
        gzip \$foo => "-"
        Paul
Re: Gzip inflate a variable
by JavaFan (Canon) on Jan 21, 2010 at 22:35 UTC
    Doesn't Compress::Zlib work for you?
Re: Gzip inflate a variable
by DStaal (Chaplain) on Jan 22, 2010 at 16:52 UTC

    Just a note of caution in amongst the other responses: Trying to compress an image that's stored in most of the common web-image formats rarely does anything useful. They all have specialized compression built in to the format, that will do better for images than gzip will.

    If it does make any (positive) difference, it's probably a good idea to look at how you are storing/generating these images. There's probably an option or so that you can use to increase the compression in the file itself, which would do more than gzip would.

      That's a very valid point - if you attempt to compress an image type that already uses compression under-the-hood (e.g. gif, jpeg), the output that is larger than the input.