imagesize 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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)