⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 size.pm

📁 稀饭伊人相册系统继承了新天堂多用户相册系统的功能
💻 PM
📖 第 1 页 / 共 2 页
字号:
################################################################################# This file copyright (c) 2000 by Randy J. Ray, all rights reserved## Copying and distribution are permitted under the terms of the Artistic# License as distributed with Perl versions 5.005 and later.################################################################################## Once upon a time, this code was lifted almost verbatim from wwwis by Alex# Knowles, alex@ed.ac.uk. Since then, even I barely recognize it. It has# contributions, fixes, additions and enhancements from all over the world.## See the file README for change history.################################################################################package Image::Size;require 5.002;use strict;use Cwd 'cwd';use File::Spec;use Symbol;use Exporter;use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $revision $VERSION            $read_in $last_pos);@ISA         = qw(Exporter);@EXPORT      = qw(imgsize);@EXPORT_OK   = qw(imgsize html_imgsize attr_imgsize);%EXPORT_TAGS = ('all' => [@EXPORT_OK]);$revision    = q$Id: Size.pm,v 1.24 2001/04/13 08:52:41 rjray Exp $;$VERSION     = "2.93";# Package lexicals - invisible to outside world, used only in imgsize## Cache of files seen, and mapping of patterns to the sizing routinemy %cache = ();my %type_map = ( '^GIF8[7,9]a'              => \&gifsize,                 "^\xFF\xD8"                => \&jpegsize,                 "^\x89PNG\x0d\x0a\x1a\x0a" => \&pngsize,                 "^P[1-7]"                  => \&ppmsize, # also XVpics                 '\#define\s+\S+\s+\d+'     => \&xbmsize,                 '\/\* XPM \*\/'            => \&xpmsize,                 '^MM\x00\x2a'              => \&tiffsize,                 '^II\x2a\x00'              => \&tiffsize,                 '^BM'                      => \&bmpsize,                 '^8BPS'                    => \&psdsize,		 '^FWS'                     => \&swfsize);## These are lexically-scoped anonymous subroutines for reading the three# types of input streams. When the input to imgsize() is typed, then the# lexical "read_in" is assigned one of these, thus allowing the individual# routines to operate on these streams abstractly.#my $read_io = sub {    my $handle = shift;    my ($length, $offset) = @_;    if (defined($offset) && ($offset != $last_pos))    {        $last_pos = $offset;        return '' if (! seek($handle, $offset, 0));    }    my ($data, $rtn) = ('', 0);    $rtn = read $handle, $data, $length;    $data = '' unless ($rtn);    $last_pos = tell $handle;    $data;};my $read_buf = sub {    my $buf = shift;    my ($length, $offset) = @_;    if (defined($offset) && ($offset != $last_pos))    {        $last_pos = $offset;        return '' if ($last_pos > length($$buf));    }    my $data = substr($$buf, $last_pos, $length);    $last_pos += length($data);    $data;};1;sub imgsize{    my $stream = shift;    my ($handle, $header);    my ($x, $y, $id, $mtime, @list);    # These only used if $stream is an existant open FH    my ($save_pos, $need_restore) = (0, 0);    # This is for when $stream is a locally-opened file    my $need_close = 0;    $header = '';    if (ref($stream) eq "SCALAR")    {        $handle = $stream;        $read_in = $read_buf;        $header = substr($$handle, 0, 256);    }    elsif (ref $stream)    {        #        # I no longer require $stream to be in the IO::* space. So I'm assuming        # you don't hose yourself by passing a ref that can't do fileops. If        # you do, you fix it.        #        $handle = $stream;        $read_in = $read_io;        $save_pos = tell $handle;        $need_restore = 1;        #        # First alteration (didn't wait long, did I?) to the existant handle:        #        # assist dain-bramaged operating systems -- SWD        # SWD: I'm a bit uncomfortable with changing the mode on a file        # that something else "owns" ... the change is global, and there        # is no way to reverse it.        # But image files ought to be handled as binary anyway.        #        binmode($handle);        seek($handle, 0, 0);        read $handle, $header, 256;        seek($handle, 0, 0);    }    else    {        $stream = File::Spec->catfile(cwd(),$stream)            unless File::Spec->file_name_is_absolute($stream);        $mtime = (stat $stream)[9];        if (-e "$stream" and exists $cache{$stream})        {            @list = split(/,/, $cache{$stream}, 4);            # Don't return the cache if the file is newer.            return @list[1 .. 3] unless ($list[0] < $mtime);            # In fact, clear it            delete $cache{$stream};        }        #first try to open the stream        $handle = gensym;        open($handle, "< $stream") or            return (undef, undef, "Can't open image file $stream: $!");        $need_close = 1;        # assist dain-bramaged operating systems -- SWD        binmode($handle);        read $handle, $header, 256;        seek($handle, 0, 0);        $read_in = $read_io;    }    $last_pos = 0;    #    # Oh pessimism... set the values of $x and $y to the error condition. If    # the grep() below matches the data to one of the known types, then the    # called subroutine will override these...    #    $id = "Data stream is not a known image file format";    $x  = undef;    $y  = undef;    grep($header =~ /$_/ && (($x, $y, $id) = &{$type_map{$_}}($handle)),         keys %type_map);    #    # Added as an afterthought: I'm probably not the only one who uses the    # same shaded-sphere image for several items on a bulleted list:    #    $cache{$stream} = join(',', $mtime, $x, $y, $id)        unless (ref $stream or (! defined $x));    #    # If we were passed an existant file handle, we need to restore the    # old filepos:    #    seek($handle, $save_pos, 0) if $need_restore;    # ...and if we opened the file ourselves, we need to close it    close($handle) if $need_close;    # results:    return (wantarray) ? ($x, $y, $id) : ();}sub html_imgsize{    my @args = imgsize(@_);    # Use lowercase and quotes so that it works with xhtml.    return ((defined $args[0]) ?            sprintf('width="%d" height="%d"', @args) :            undef);}sub attr_imgsize{    my @args = imgsize(@_);    return ((defined $args[0]) ?            (('-width', '-height', @args)[0, 2, 1, 3]) :            undef);}# This used only in gifsize:sub img_eof{    my $stream = shift;    return ($last_pos >= length($$stream)) if (ref($stream) eq "SCALAR");    eof $stream;}############################################################################ Subroutine gets the size of the specified GIF###########################################################################sub gifsize{    my $stream = shift;    my ($cmapsize, $buf, $h, $w, $x, $y, $type);    my $gif_blockskip = sub {        my ($skip, $type) = @_;        my ($lbuf);        &$read_in($stream, $skip);        # Skip header (if any)        while (1)        {            if (&img_eof($stream))            {                return (undef, undef,                        "Invalid/Corrupted GIF (at EOF in GIF $type)");            }            $lbuf = &$read_in($stream, 1);        # Block size            last if ord($lbuf) == 0;     # Block terminator            &$read_in($stream, ord($lbuf));  # Skip data        }    };    $type = &$read_in($stream, 6);    if (length($buf = &$read_in($stream, 7)) != 7 )    {        return (undef, undef, "Invalid/Corrupted GIF (bad header)");    }    ($x) = unpack("x4 C", $buf);    if ($x & 0x80)    {        $cmapsize = 3 * (2**(($x & 0x07) + 1));        if (! &$read_in($stream, $cmapsize))        {            return (undef, undef,                    "Invalid/Corrupted GIF (global color map too small?)");        }    }  FINDIMAGE:    while (1)    {        if (&img_eof($stream))        {            return (undef, undef,                    "Invalid/Corrupted GIF (at EOF w/o Image Descriptors)");        }        $buf = &$read_in($stream, 1);        ($x) = unpack("C", $buf);        if ($x == 0x2c)        {            # Image Descriptor (GIF87a, GIF89a 20.c.i)            if (length($buf = &$read_in($stream, 8)) != 8)            {                return (undef, undef,                        "Invalid/Corrupted GIF (missing image header?)");            }            ($x, $w, $y, $h) = unpack("x4 C4", $buf);            $x += $w * 256;            $y += $h * 256;            return ($x, $y, 'GIF');        }        if ($x == 0x21)        {            # Extension Introducer (GIF89a 23.c.i, could also be in GIF87a)            $buf = &$read_in($stream, 1);            ($x) = unpack("C", $buf);            if ($x == 0xF9)            {                # Graphic Control Extension (GIF89a 23.c.ii)                &$read_in($stream, 6);    # Skip it                next FINDIMAGE;       # Look again for Image Descriptor            }            elsif ($x == 0xFE)            {                # Comment Extension (GIF89a 24.c.ii)                &$gif_blockskip(0, "Comment");                next FINDIMAGE;       # Look again for Image Descriptor            }            elsif ($x == 0x01)            {                # Plain Text Label (GIF89a 25.c.ii)                &$gif_blockskip(13, "text data");                next FINDIMAGE;       # Look again for Image Descriptor            }            elsif ($x == 0xFF)            {                # Application Extension Label (GIF89a 26.c.ii)                &$gif_blockskip(12, "application data");                next FINDIMAGE;       # Look again for Image Descriptor            }            else            {                return (undef, undef,                        sprintf("Invalid/Corrupted GIF (Unknown " .                                "extension %#x)", $x));            }        }        else        {            return (undef, undef,                    sprintf("Invalid/Corrupted GIF (Unknown code %#x)",                            $x));        }    }}sub xbmsize{    my $stream = shift;    my $input;    my ($x, $y, $id) = (undef, undef, "Could not determine XBM size");    $input = &$read_in($stream, 1024);    if ($input =~ /^\#define\s*\S*\s*(\d+)\s*\n\#define\s*\S*\s*(\d+)/si)    {        ($x, $y) = ($1, $2);        $id = 'XBM';    }    ($x, $y, $id);}# Added by Randy J. Ray, 30 Jul 1996# Size an XPM file by looking for the "X Y N W" line, where X and Y are# dimensions, N is the total number of colors defined, and W is the width of# a color in the ASCII representation, in characters. We only care about X & Y.sub xpmsize{    my $stream = shift;    my $line;    my ($x, $y, $id) = (undef, undef, "Could not determine XPM size");    while ($line = &$read_in($stream, 1024))    {        next unless ($line =~ /"\s*(\d+)\s+(\d+)(\s+\d+\s+\d+){1,2}\s*"/s);        ($x, $y) = ($1, $2);        $id = 'XPM';        last;    }    ($x, $y, $id);}# pngsize : gets the width & height (in pixels) of a png file# cor this program is on the cutting edge of technology! (pity it's blunt!)## Re-written and tested by tmetro@vl.comsub pngsize{    my $stream = shift;    my ($x, $y, $id) = (undef, undef, "could not determine PNG size");    my ($offset, $length);    # Offset to first Chunk Type code = 8-byte ident + 4-byte chunk length + 1    $offset = 12; $length = 4;    if (&$read_in($stream, $length, $offset) eq 'IHDR')    {        # IHDR = Image Header        $length = 8;        ($x, $y) = unpack("NN", &$read_in($stream, $length));        $id = 'PNG';    }    ($x, $y, $id);}# jpegsize: gets the width and height (in pixels) of a jpeg file# Andrew Tong, werdna@ugcs.caltech.edu           February 14, 1995# modified slightly by alex@ed.ac.uk# and further still by rjray@tsoft.com# optimization and general re-write from tmetro@vl.com

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -