fixes #118: flash uploads are broken
This commit is contained in:
295
vendor/plugins/imagesize/lib/image_size.rb
vendored
Executable file
295
vendor/plugins/imagesize/lib/image_size.rb
vendored
Executable file
@@ -0,0 +1,295 @@
|
||||
#!ruby
|
||||
# encoding: US-ASCII
|
||||
|
||||
class ImageSize
|
||||
require "stringio"
|
||||
|
||||
# Image Type Constants
|
||||
module Type
|
||||
OTHER = "OTHER"
|
||||
GIF = "GIF"
|
||||
PNG = "PNG"
|
||||
JPEG = "JPEG"
|
||||
BMP = "BMP"
|
||||
PPM = "PPM" # PPM is like PBM, PGM, & XV
|
||||
PBM = "PBM"
|
||||
PGM = "PGM"
|
||||
# XV = "XV"
|
||||
XBM = "XBM"
|
||||
TIFF = "TIFF"
|
||||
XPM = "XPM"
|
||||
PSD = "PSD"
|
||||
SWF = "SWF"
|
||||
end
|
||||
|
||||
JpegCodeCheck = [
|
||||
"\xc0", "\xc1", "\xc2", "\xc3",
|
||||
"\xc5", "\xc6", "\xc7",
|
||||
"\xc9", "\xca", "\xcb",
|
||||
"\xcd", "\xce", "\xcf",
|
||||
]
|
||||
|
||||
# image type list
|
||||
def ImageSize.type_list
|
||||
Type.constants
|
||||
end
|
||||
|
||||
# receive image & make size
|
||||
# argument 1 is image String, StringIO or IO
|
||||
# argument 2 is type(ImageSize::Type::GIF and so on.) or nil
|
||||
def initialize(img_data, img_type = nil)
|
||||
@img_data = img_data.dup
|
||||
@img_width = nil
|
||||
@img_height = nil
|
||||
@img_type = nil
|
||||
|
||||
if @img_data.is_a?(IO)
|
||||
img_top = @img_data.read(1024)
|
||||
img_io = def_read_o(@img_data)
|
||||
elsif @img_data.is_a?(StringIO)
|
||||
img_top = @img_data.read(1024)
|
||||
img_io = def_read_o(@img_data)
|
||||
elsif @img_data.is_a?(String)
|
||||
img_top = @img_data[0, 1024]
|
||||
# img_io = StringIO.open(@img_data){|sio| io = def_read_o(sio); io }
|
||||
img_io = StringIO.open(@img_data)
|
||||
img_io = def_read_o(img_io)
|
||||
else
|
||||
raise "argument class error!! #{img_data.type}"
|
||||
end
|
||||
|
||||
if @img_type.nil?
|
||||
@img_type = check_type(img_top)
|
||||
else
|
||||
type = Type.constants.find{|t| img_type == t }
|
||||
raise("type is failed. #{img_type}\n") if !type
|
||||
@img_type = img_type
|
||||
end
|
||||
|
||||
if @img_type != Type::OTHER
|
||||
@img_width, @img_height = self.__send__("measure_#{@img_type}", img_io)
|
||||
else
|
||||
@img_width, @img_height = [nil, nil]
|
||||
end
|
||||
|
||||
if @img_data.is_a?(String)
|
||||
img_io.close
|
||||
end
|
||||
end
|
||||
|
||||
# get image type
|
||||
# ex. "GIF", "PNG", "JPEG"
|
||||
def get_type; @img_type; end
|
||||
|
||||
# get image height
|
||||
def get_height
|
||||
if @img_type == Type::OTHER then nil else @img_height end
|
||||
end
|
||||
|
||||
# get image width
|
||||
def get_width
|
||||
if @img_type == Type::OTHER then nil else @img_width end
|
||||
end
|
||||
|
||||
# get image width and height(Array)
|
||||
def get_size
|
||||
[self.get_width, self.get_height]
|
||||
end
|
||||
|
||||
alias :height :get_height
|
||||
alias :h :get_height
|
||||
|
||||
alias :width :get_width
|
||||
alias :w :get_width
|
||||
|
||||
alias :size :get_size
|
||||
|
||||
|
||||
private
|
||||
|
||||
# define read_o
|
||||
def def_read_o(io)
|
||||
io.seek(0, 0)
|
||||
# define Singleton-method definition to IO (byte, offset)
|
||||
def io.read_o(length = 1, offset = nil)
|
||||
self.seek(offset, 0) if offset
|
||||
ret = self.read(length)
|
||||
raise "cannot read!!" unless ret
|
||||
ret
|
||||
end
|
||||
io
|
||||
end
|
||||
|
||||
def check_type(img_top)
|
||||
if img_top =~ /^GIF8[7,9]a/ then Type::GIF
|
||||
elsif img_top[0, 8] == "\x89PNG\x0d\x0a\x1a\x0a" then Type::PNG
|
||||
elsif img_top[0, 2] == "\xFF\xD8" then Type::JPEG
|
||||
elsif img_top[0, 2] == 'BM' then Type::BMP
|
||||
elsif img_top =~ /^P[1-7]/ then Type::PPM
|
||||
elsif img_top =~ /\#define\s+\S+\s+\d+/ then Type::XBM
|
||||
elsif img_top[0, 4] == "MM\x00\x2a" then Type::TIFF
|
||||
elsif img_top[0, 4] == "II\x2a\x00" then Type::TIFF
|
||||
elsif img_top =~ /\/\* XPM \*\// then Type::XPM
|
||||
elsif img_top[0, 4] == "8BPS" then Type::PSD
|
||||
elsif img_top[1, 2] == "WS" then Type::SWF
|
||||
else Type::OTHER
|
||||
end
|
||||
end
|
||||
|
||||
def measure_GIF(img_io)
|
||||
img_io.read_o(6)
|
||||
img_io.read_o(4).unpack('vv')
|
||||
end
|
||||
|
||||
def measure_PNG(img_io)
|
||||
img_io.read_o(12)
|
||||
raise "This file is not PNG." unless img_io.read_o(4) == "IHDR"
|
||||
img_io.read_o(8).unpack('NN')
|
||||
end
|
||||
|
||||
def measure_JPEG(img_io)
|
||||
c_marker = "\xFF" # Section marker.
|
||||
img_io.read_o(2)
|
||||
while(true)
|
||||
marker, code, length = img_io.read_o(4).unpack('aan')
|
||||
raise "JPEG marker not found!" if marker != c_marker
|
||||
|
||||
if JpegCodeCheck.include?(code)
|
||||
height, width = img_io.read_o(5).unpack('xnn')
|
||||
return([width, height])
|
||||
end
|
||||
img_io.read_o(length - 2)
|
||||
end
|
||||
end
|
||||
|
||||
def measure_BMP(img_io)
|
||||
img_io.read_o(26).unpack("x18VV");
|
||||
end
|
||||
|
||||
def measure_PPM(img_io)
|
||||
header = img_io.read_o(1024)
|
||||
header.gsub!(/^\#[^\n\r]*/m, "")
|
||||
header =~ /^(P[1-6])\s+?(\d+)\s+?(\d+)/m
|
||||
width = $2.to_i; height = $3.to_i
|
||||
case $1
|
||||
when "P1", "P4" then @img_type = "PBM"
|
||||
when "P2", "P5" then @img_type = "PGM"
|
||||
when "P3", "P6" then @img_type = "PPM"
|
||||
# when "P7"
|
||||
# @img_type = "XV"
|
||||
# header =~ /IMGINFO:(\d+)x(\d+)/m
|
||||
# width = $1.to_i; height = $2.to_i
|
||||
end
|
||||
[width, height]
|
||||
end
|
||||
|
||||
alias :measure_PGM :measure_PPM
|
||||
alias :measure_PBM :measure_PPM
|
||||
|
||||
def measure_XBM(img_io)
|
||||
img_io.read_o(1024) =~ /^\#define\s*\S*\s*(\d+)\s*\n\#define\s*\S*\s*(\d+)/mi
|
||||
[$1.to_i, $2.to_i]
|
||||
end
|
||||
|
||||
def measure_XPM(img_io)
|
||||
width = height = nil
|
||||
while(line = img_io.read_o(1024))
|
||||
if line =~ /"\s*(\d+)\s+(\d+)(\s+\d+\s+\d+){1,2}\s*"/m
|
||||
width = $1.to_i; height = $2.to_i
|
||||
break
|
||||
end
|
||||
end
|
||||
[width, height]
|
||||
end
|
||||
|
||||
def measure_PSD(img_io)
|
||||
img_io.read_o(26).unpack("x14NN")
|
||||
end
|
||||
|
||||
def measure_TIFF(img_io)
|
||||
endian = if (img_io.read_o(4) =~ /II\x2a\x00/o) then 'v' else 'n' end
|
||||
# 'v' little-endian 'n' default to big-endian
|
||||
|
||||
packspec = [
|
||||
nil, # nothing (shouldn't happen)
|
||||
'C', # BYTE (8-bit unsigned integer)
|
||||
nil, # ASCII
|
||||
endian, # SHORT (16-bit unsigned integer)
|
||||
endian.upcase, # LONG (32-bit unsigned integer)
|
||||
nil, # RATIONAL
|
||||
'c', # SBYTE (8-bit signed integer)
|
||||
nil, # UNDEFINED
|
||||
endian, # SSHORT (16-bit unsigned integer)
|
||||
endian.upcase, # SLONG (32-bit unsigned integer)
|
||||
]
|
||||
|
||||
offset = img_io.read_o(4).unpack(endian.upcase)[0] # Get offset to IFD
|
||||
|
||||
ifd = img_io.read_o(2, offset)
|
||||
num_dirent = ifd.unpack(endian)[0] # Make it useful
|
||||
offset += 2
|
||||
num_dirent = offset + (num_dirent * 12); # Calc. maximum offset of IFD
|
||||
|
||||
ifd = width = height = nil
|
||||
while(width.nil? || height.nil?)
|
||||
ifd = img_io.read_o(12, offset) # Get first directory entry
|
||||
break if (ifd.nil? || (offset > num_dirent))
|
||||
offset += 12
|
||||
tag = ifd.unpack(endian)[0] # ...and decode its tag
|
||||
type = ifd[2, 2].unpack(endian)[0] # ...and the data type
|
||||
|
||||
# Check the type for sanity.
|
||||
next if (type > packspec.size + 0) || (packspec[type].nil?)
|
||||
if tag == 0x0100 # Decode the value
|
||||
width = ifd[8, 4].unpack(packspec[type])[0]
|
||||
elsif tag == 0x0101 # Decode the value
|
||||
height = ifd[8, 4].unpack(packspec[type])[0]
|
||||
end
|
||||
end
|
||||
|
||||
raise "#{if width.nil? then 'width not defined.' end} #{if height.nil? then 'height not defined.' end}" if width.nil? || height.nil?
|
||||
[width, height]
|
||||
end
|
||||
|
||||
def measure_SWF(img_io)
|
||||
header = img_io.read_o(9)
|
||||
|
||||
sig1 = header[0,1]
|
||||
sig2 = header[1,1]
|
||||
sig3 = header[2,1]
|
||||
|
||||
if !((sig1 == 'F' || sig1 == 'C') && sig2 == 'W' && sig3 == 'S')
|
||||
raise("This file is not SWF.")
|
||||
end
|
||||
|
||||
bit_length = Integer("0b#{header.unpack('@8B5')[0]}")
|
||||
header << img_io.read_o(bit_length*4/8+1)
|
||||
str = header.unpack("@8B#{5+bit_length*4}")[0]
|
||||
last = 5
|
||||
x_min = Integer("0b#{str[last,bit_length]}")
|
||||
x_max = Integer("0b#{str[(last += bit_length),bit_length]}")
|
||||
y_min = Integer("0b#{str[(last += bit_length),bit_length]}")
|
||||
y_max = Integer("0b#{str[(last += bit_length),bit_length]}")
|
||||
width = (x_max - x_min)/20
|
||||
height = (y_max - y_min)/20
|
||||
[width, height]
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if __FILE__ == $0
|
||||
print "TypeList: #{ImageSize.type.inspect}\n"
|
||||
|
||||
Dir.glob("*").each do |file|
|
||||
print "#{file} (string)\n"
|
||||
open(file, "rb") do |fh|
|
||||
img = ImageSize.new(fh.read)
|
||||
print <<-EOF
|
||||
type: #{img.get_type.inspect}
|
||||
width: #{img.get_width.inspect}
|
||||
height: #{img.get_height.inspect}
|
||||
EOF
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
9
vendor/plugins/imagesize/lib/image_size/version.rb
vendored
Executable file
9
vendor/plugins/imagesize/lib/image_size/version.rb
vendored
Executable file
@@ -0,0 +1,9 @@
|
||||
module Imagesize #:nodoc:
|
||||
module VERSION #:nodoc:
|
||||
MAJOR = 0
|
||||
MINOR = 1
|
||||
TINY = 1
|
||||
|
||||
STRING = [MAJOR, MINOR, TINY].join('.')
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user