imagesize 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ +++ 0.0.1 2007-04-19
2
+
3
+ + 1 major enhancement:
4
+ + Initial release
@@ -0,0 +1,28 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ lib/image_size.rb
6
+ lib/image_size/version.rb
7
+ lib/image_size/image_size.rb
8
+ scripts/txt2html
9
+ setup.rb
10
+ test/test_helper.rb
11
+ test/test_image_size.rb
12
+ test/2-4-7.png
13
+ test/4_1_2.gif
14
+ test/bmp.bmp
15
+ test/cursor.xbm
16
+ test/detect.swf
17
+ test/pbm.pbm
18
+ test/pcx.pcx
19
+ test/pgm.pgm
20
+ test/test.xpm
21
+ test/tiff.tiff
22
+ test/tokyo_tower.jpg
23
+ test/tower_e.gif.psd
24
+ website/index.html
25
+ website/index.txt
26
+ website/javascripts/rounded_corners_lite.inc.js
27
+ website/stylesheets/screen.css
28
+ website/template.rhtml
@@ -0,0 +1,3 @@
1
+ README for imagesize
2
+ ====================
3
+
@@ -0,0 +1,97 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/clean'
4
+ require 'rake/testtask'
5
+ require 'rake/packagetask'
6
+ require 'rake/gempackagetask'
7
+ require 'rake/rdoctask'
8
+ require 'rake/contrib/rubyforgepublisher'
9
+ require 'fileutils'
10
+ require 'hoe'
11
+ include FileUtils
12
+ require File.join(File.dirname(__FILE__), 'lib', 'image_size', 'version')
13
+
14
+ AUTHOR = 'Keisuke Minami' # can also be an array of Authors
15
+ EMAIL = "keisuke@rccn.com"
16
+ DESCRIPTION = "measure image size(GIF, PNG, JPEG ,,, etc)"
17
+ GEM_NAME = 'imagesize' # what ppl will type to install your gem
18
+ RUBYFORGE_PROJECT = 'imagesize' # The unix name for your project
19
+ HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
20
+
21
+
22
+ NAME = "imagesize"
23
+ REV = nil # UNCOMMENT IF REQUIRED: File.read(".svn/entries")[/committed-rev="(d+)"/, 1] rescue nil
24
+ VERS = ENV['VERSION'] || (Imagesize::VERSION::STRING + (REV ? ".#{REV}" : ""))
25
+ CLEAN.include ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store']
26
+ RDOC_OPTS = ['--quiet', '--title', 'imagesize documentation',
27
+ "--opname", "index.html",
28
+ "--line-numbers",
29
+ "--main", "README",
30
+ "--inline-source"]
31
+
32
+ class Hoe
33
+ def extra_deps
34
+ @extra_deps.reject { |x| Array(x).first == 'hoe' }
35
+ end
36
+ end
37
+
38
+ # Generate all the Rake tasks
39
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
40
+ hoe = Hoe.new(GEM_NAME, VERS) do |p|
41
+ p.author = AUTHOR
42
+ p.description = DESCRIPTION
43
+ p.email = EMAIL
44
+ p.summary = DESCRIPTION
45
+ p.url = HOMEPATH
46
+ p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
47
+ p.test_globs = ["test/**/test_*.rb"]
48
+ p.clean_globs = CLEAN #An array of file patterns to delete on clean.
49
+
50
+ # == Optional
51
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
52
+ #p.extra_deps = [] # An array of rubygem dependencies [name, version], e.g. [ ['active_support', '>= 1.3.1'] ]
53
+ #p.spec_extras = {} # A hash of extra values to set in the gemspec.
54
+ end
55
+
56
+
57
+ desc 'Generate website files'
58
+ task :website_generate do
59
+ Dir['website/**/*.txt'].each do |txt|
60
+ sh %{ ruby scripts/txt2html #{txt} > #{txt.gsub(/txt$/,'html')} }
61
+ end
62
+ end
63
+
64
+ desc 'Upload website files to rubyforge'
65
+ task :website_upload do
66
+ config = YAML.load(File.read(File.expand_path("~/.rubyforge/user-config.yml")))
67
+ host = "#{config["username"]}@rubyforge.org"
68
+ remote_dir = "/var/www/gforge-projects/#{RUBYFORGE_PROJECT}/"
69
+ # remote_dir = "/var/www/gforge-projects/#{RUBYFORGE_PROJECT}/#{GEM_NAME}"
70
+ local_dir = 'website'
71
+ sh %{rsync -av #{local_dir}/ #{host}:#{remote_dir}}
72
+ end
73
+
74
+ desc 'Generate and upload website files'
75
+ task :website => [:website_generate, :website_upload]
76
+
77
+
78
+
79
+ ### ここから持ってきた設定
80
+ ### http://d.hatena.ne.jp/secondlife/20061106/1162785661
81
+ Rake::RDocTask.new do |rdoc|
82
+ rdoc.rdoc_dir = 'html'
83
+ rdoc.options += RDOC_OPTS
84
+ rdoc.template = "#{ENV['template']}.rb" if ENV['template']
85
+ if ENV['DOC_FILES']
86
+ rdoc.rdoc_files.include(ENV['DOC_FILES'].split(/,\s*/))
87
+ else
88
+ # rdoc.rdoc_files.include('README', 'CHANGELOG')
89
+ rdoc.rdoc_files.include('README.txt')
90
+ rdoc.rdoc_files.include('lib/**/*.rb')
91
+ end
92
+ end
93
+
94
+ desc "Publish to RubyForge"
95
+ task :rubyforge => [:rdoc, :package] do
96
+ Rake::RubyForgePublisher.new(RUBYFORGE_PROJECT, 'gawgaw61').upload
97
+ end
@@ -0,0 +1,5 @@
1
+ #Dir[File.join(File.dirname(__FILE__), 'imagesize/**/*.rb')].sort.each { |lib| require lib }
2
+
3
+ require 'image_size/image_size.rb'
4
+ require 'image_size/version.rb'
5
+
@@ -0,0 +1,284 @@
1
+ #!ruby
2
+
3
+ class ImageSize
4
+ # Image Type Constants
5
+ module Type
6
+ OTHER = "OTHER"
7
+ GIF = "GIF"
8
+ PNG = "PNG"
9
+ JPEG = "JPEG"
10
+ BMP = "BMP"
11
+ PPM = "PPM" # PPM is like PBM, PGM, & XV
12
+ PBM = "PBM"
13
+ PGM = "PGM"
14
+ # XV = "XV"
15
+ XBM = "XBM"
16
+ TIFF = "TIFF"
17
+ XPM = "XPM"
18
+ PSD = "PSD"
19
+ PCX = "PCX"
20
+ SWF = "SWF"
21
+ end
22
+
23
+ JpegCodeCheck = [
24
+ "\xc0", "\xc1", "\xc2", "\xc3",
25
+ "\xc5", "\xc6", "\xc7",
26
+ "\xc9", "\xca", "\xcb",
27
+ "\xcd", "\xce", "\xcf",
28
+ ]
29
+
30
+ # image type list
31
+ def ImageSize.type_list
32
+ Type.constants
33
+ end
34
+
35
+ # receive image & make size
36
+ # argument is image String or IO
37
+ def initialize(img_data, img_type = nil)
38
+ @img_data = img_data.dup
39
+ @img_wedth = nil
40
+ @img_height = nil
41
+
42
+ if @img_data.is_a?(IO)
43
+ @img_top = @img_data.read(128)
44
+ @img_data.seek(0, 0)
45
+ # define Singleton-method definition to IO (byte, offset)
46
+ def @img_data.read_o(length = 1, offset = nil)
47
+ self.seek(offset, 0) if offset
48
+ ret = self.read(length)
49
+ raise "cannot read!!" unless ret
50
+ ret
51
+ end
52
+ elsif @img_data.is_a?(String)
53
+ @img_top = @img_data[0, 128]
54
+ # define Singleton-method definition to String (byte, offset)
55
+ def @img_data.read_o(length = 1, offset = nil)
56
+ @img_offset = 0 if !(defined?(@img_offset))
57
+ @img_offset = offset if offset
58
+ ret = self[@img_offset, length]
59
+ @img_offset += length
60
+ ret
61
+ end
62
+ else
63
+ raise "argument class error!! #{img_data.type}"
64
+ end
65
+
66
+ if img_type.nil?
67
+ @img_type = check_type()
68
+ else
69
+ match = false
70
+ Type.constants.each do |t|
71
+ match = true if img_type == t
72
+ end
73
+ raise("img_type is failed. #{img_type}\n") if match == false
74
+ @img_type = img_type
75
+ end
76
+
77
+ eval("@img_width, @img_height = measure_" + @img_type + "()") if @img_type != Type::OTHER
78
+ end
79
+
80
+ # get parameter
81
+ def get_type; @img_type; end
82
+ def get_height
83
+ if @img_type == Type::OTHER then nil else @img_height end
84
+ end
85
+ def get_width
86
+ if @img_type == Type::OTHER then nil else @img_width end
87
+ end
88
+
89
+ def check_type()
90
+ if @img_top =~ /^GIF8[7,9]a/ then Type::GIF
91
+ elsif @img_top[0, 8] == "\x89PNG\x0d\x0a\x1a\x0a" then Type::PNG
92
+ elsif @img_top[0, 2] == "\xFF\xD8" then Type::JPEG
93
+ elsif @img_top[0, 2] == 'BM' then Type::BMP
94
+ elsif @img_top =~ /^P[1-7]/ then Type::PPM
95
+ elsif @img_top =~ /\#define\s+\S+\s+\d+/ then Type::XBM
96
+ elsif @img_top[0, 4] == "MM\x00\x2a" then Type::TIFF
97
+ elsif @img_top[0, 4] == "II\x2a\x00" then Type::TIFF
98
+ elsif @img_top =~ /\/\* XPM \*\// then Type::XPM
99
+ elsif @img_top[0, 4] == "8BPS" then Type::PSD
100
+ elsif @img_top[1, 2] == "WS" then Type::SWF
101
+ elsif @img_top[0] == 10 then Type::PCX
102
+ else Type::OTHER
103
+ end
104
+ end
105
+ private(:check_type)
106
+
107
+ def measure_GIF()
108
+ @img_data.read_o(6)
109
+ @img_data.read_o(4).unpack('vv')
110
+ end
111
+ private(:measure_GIF)
112
+
113
+ def measure_PNG()
114
+ @img_data.read_o(12)
115
+ raise "This file is not PNG." unless @img_data.read_o(4) == "IHDR"
116
+ @img_data.read_o(8).unpack('NN')
117
+ end
118
+ private(:measure_PNG)
119
+
120
+ def measure_JPEG()
121
+ c_marker = "\xFF" # Section marker.
122
+ @img_data.read_o(2)
123
+ while(true)
124
+ marker, code, length = @img_data.read_o(4).unpack('aan')
125
+ raise "JPEG marker not found!" if marker != c_marker
126
+
127
+ if JpegCodeCheck.include?(code)
128
+ height, width = @img_data.read_o(5).unpack('xnn')
129
+ return([width, height])
130
+ end
131
+ @img_data.read_o(length - 2)
132
+ end
133
+ end
134
+ private(:measure_JPEG)
135
+
136
+ def measure_BMP()
137
+ @img_data.read_o(26).unpack("x18VV");
138
+ end
139
+ private(:measure_BMP)
140
+
141
+ def measure_PPM()
142
+ header = @img_data.read_o(1024)
143
+ header.gsub!(/^\#[^\n\r]*/m, "")
144
+ header =~ /^(P[1-6])\s+?(\d+)\s+?(\d+)/m
145
+ width = $2.to_i; height = $3.to_i
146
+ case $1
147
+ when "P1", "P4" then @img_type = "PBM"
148
+ when "P2", "P5" then @img_type = "PGM"
149
+ when "P3", "P6" then @img_type = "PPM"
150
+ # when "P7"
151
+ # @img_type = "XV"
152
+ # header =~ /IMGINFO:(\d+)x(\d+)/m
153
+ # width = $1.to_i; height = $2.to_i
154
+ end
155
+ [width, height]
156
+ end
157
+ private(:measure_PPM)
158
+
159
+ alias :measure_PGM :measure_PPM
160
+ private(:measure_PGM)
161
+ alias :measure_PBM :measure_PPM
162
+ private(:measure_PBM)
163
+
164
+ def measure_XBM()
165
+ @img_data.read_o(1024) =~ /^\#define\s*\S*\s*(\d+)\s*\n\#define\s*\S*\s*(\d+)/mi
166
+ [$1.to_i, $2.to_i]
167
+ end
168
+ private(:measure_XBM)
169
+
170
+ def measure_XPM()
171
+ width = height = nil
172
+ while(line = @img_data.read_o(1024))
173
+ if line =~ /"\s*(\d+)\s+(\d+)(\s+\d+\s+\d+){1,2}\s*"/m
174
+ width = $1.to_i; height = $2.to_i
175
+ break
176
+ end
177
+ end
178
+ [width, height]
179
+ end
180
+ private(:measure_XPM)
181
+
182
+ def measure_PSD()
183
+ @img_data.read_o(26).unpack("x14NN")
184
+ end
185
+ private(:measure_PSD)
186
+
187
+ def measure_TIFF()
188
+ endian = if (@img_data.read_o(4) =~ /II\x2a\x00/o) then 'v' else 'n' end
189
+ # 'v' little-endian 'n' default to big-endian
190
+
191
+ packspec = [
192
+ nil, # nothing (shouldn't happen)
193
+ 'C', # BYTE (8-bit unsigned integer)
194
+ nil, # ASCII
195
+ endian, # SHORT (16-bit unsigned integer)
196
+ endian.upcase, # LONG (32-bit unsigned integer)
197
+ nil, # RATIONAL
198
+ 'c', # SBYTE (8-bit signed integer)
199
+ nil, # UNDEFINED
200
+ endian, # SSHORT (16-bit unsigned integer)
201
+ endian.upcase, # SLONG (32-bit unsigned integer)
202
+ ]
203
+
204
+ offset = @img_data.read_o(4).unpack(endian.upcase)[0] # Get offset to IFD
205
+
206
+ ifd = @img_data.read_o(2, offset)
207
+ num_dirent = ifd.unpack(endian)[0] # Make it useful
208
+ offset += 2
209
+ num_dirent = offset + (num_dirent * 12); # Calc. maximum offset of IFD
210
+
211
+ ifd = width = height = nil
212
+ while(width.nil? || height.nil?)
213
+ ifd = @img_data.read_o(12, offset) # Get first directory entry
214
+ break if (ifd.nil? || (offset > num_dirent))
215
+ offset += 12
216
+ tag = ifd.unpack(endian)[0] # ...and decode its tag
217
+ type = ifd[2, 2].unpack(endian)[0] # ...and the data type
218
+
219
+ # Check the type for sanity.
220
+ next if (type > packspec.size + 0) || (packspec[type].nil?)
221
+ if tag == 0x0100 # Decode the value
222
+ width = ifd[8, 4].unpack(packspec[type])[0]
223
+ elsif tag == 0x0101 # Decode the value
224
+ height = ifd[8, 4].unpack(packspec[type])[0]
225
+ end
226
+ end
227
+
228
+ raise "#{if width.nil? then 'width not defined.' end} #{if height.nil? then 'height not defined.' end}" if width.nil? || height.nil?
229
+ [width, height]
230
+ end
231
+ private(:measure_TIFF)
232
+
233
+ def measure_PCX()
234
+ header = @img_data.read_o(128)
235
+ head_part = header.unpack('C4S4')
236
+ width = head_part[6] - head_part[4] + 1
237
+ height = head_part[7] - head_part[5] + 1
238
+ [width, height]
239
+ end
240
+ private(:measure_PCX)
241
+
242
+ def measure_SWF()
243
+ header = @img_data.read_o(9)
244
+
245
+ sig1 = header[0,1]
246
+ sig2 = header[1,1]
247
+ sig3 = header[2,1]
248
+
249
+ if !((sig1 == 'F' || sig1 == 'C') && sig2 == 'W' && sig3 == 'S')
250
+ raise("This file is not SWF.")
251
+ end
252
+
253
+ bit_length = Integer("0b#{header.unpack('@8B5')}")
254
+ header << @img_data.read_o(bit_length*4/8+1)
255
+ str = header.unpack("@8B#{5+bit_length*4}")[0]
256
+ last = 5
257
+ x_min = Integer("0b#{str[last,bit_length]}")
258
+ x_max = Integer("0b#{str[(last += bit_length),bit_length]}")
259
+ y_min = Integer("0b#{str[(last += bit_length),bit_length]}")
260
+ y_max = Integer("0b#{str[(last += bit_length),bit_length]}")
261
+ width = (x_max - x_min)/20
262
+ height = (y_max - y_min)/20
263
+ [width, height]
264
+ end
265
+ private(:measure_PCX)
266
+ end
267
+
268
+
269
+ if __FILE__ == $0
270
+ print "TypeList: #{ImageSize.type.inspect}\n"
271
+
272
+ Dir.glob("*").each do |file|
273
+ print "#{file} (string)\n"
274
+ open(file, "rb") do |fh|
275
+ img = ImageSize.new(fh.read)
276
+ print <<-EOF
277
+ type: #{img.get_type.inspect}
278
+ width: #{img.get_width.inspect}
279
+ height: #{img.get_height.inspect}
280
+ EOF
281
+ end
282
+ end
283
+ end
284
+
@@ -0,0 +1,9 @@
1
+ module Imagesize #:nodoc:
2
+ module VERSION #:nodoc:
3
+ MAJOR = 0
4
+ MINOR = 0
5
+ TINY = 1
6
+
7
+ STRING = [MAJOR, MINOR, TINY].join('.')
8
+ end
9
+ end
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'redcloth'
5
+ require 'syntax/convertors/html'
6
+ require 'erb'
7
+ require File.dirname(__FILE__) + '/../lib/image_size/version.rb'
8
+
9
+ version = Imagesize::VERSION::STRING
10
+ download = 'http://rubyforge.org/projects/imagesize'
11
+
12
+ class Fixnum
13
+ def ordinal
14
+ # teens
15
+ return 'th' if (10..19).include?(self % 100)
16
+ # others
17
+ case self % 10
18
+ when 1: return 'st'
19
+ when 2: return 'nd'
20
+ when 3: return 'rd'
21
+ else return 'th'
22
+ end
23
+ end
24
+ end
25
+
26
+ class Time
27
+ def pretty
28
+ return "#{mday}#{mday.ordinal} #{strftime('%B')} #{year}"
29
+ end
30
+ end
31
+
32
+ def convert_syntax(syntax, source)
33
+ return Syntax::Convertors::HTML.for_syntax(syntax).convert(source).gsub(%r!^<pre>|</pre>$!,'')
34
+ end
35
+
36
+ if ARGV.length >= 1
37
+ src, template = ARGV
38
+ template ||= File.dirname(__FILE__) + '/../website/template.rhtml'
39
+
40
+ else
41
+ puts("Usage: #{File.split($0).last} source.txt [template.rhtml] > output.html")
42
+ exit!
43
+ end
44
+
45
+ template = ERB.new(File.open(template).read)
46
+
47
+ title = nil
48
+ body = nil
49
+ File.open(src) do |fsrc|
50
+ title_text = fsrc.readline
51
+ body_text = fsrc.read
52
+ syntax_items = []
53
+ body_text.gsub!(%r!<(pre|code)[^>]*?syntax=['"]([^'"]+)[^>]*>(.*?)</>!m){
54
+ ident = syntax_items.length
55
+ element, syntax, source = $1, $2, $3
56
+ syntax_items << "<#{element} class='syntax'>#{convert_syntax(syntax, source)}</#{element}>"
57
+ "syntax-temp-#{ident}"
58
+ }
59
+ title = RedCloth.new(title_text).to_html.gsub(%r!<.*?>!,'').strip
60
+ body = RedCloth.new(body_text).to_html
61
+ body.gsub!(%r!(?:<pre><code>)?syntax-temp-(d+)(?:</code></pre>)?!){ syntax_items[$1.to_i] }
62
+ end
63
+ stat = File.stat(src)
64
+ created = stat.ctime
65
+ modified = stat.mtime
66
+
67
+ $stdout << template.result(binding)