fastimage 1.5.5 → 1.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.textile +13 -2
- data/lib/fastimage.rb +149 -128
- data/test/fixtures/test.psd +0 -0
- data/test/fixtures/test4.jpg +0 -0
- data/test/test.rb +21 -19
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 938eee083d0e447dd8fb8159f9a6dc3db70af030
|
4
|
+
data.tar.gz: d6f061def90b88547f941bc93ade56471603fe92
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f9ff437cedb77b51854cd6869d0fcf514186004f09cc4e413e1cf8610b1f63d434ea3ee5e45e9b137b289243550b0b4b0040248419fe629f12dac4a142286288
|
7
|
+
data.tar.gz: bf5c6a6adf2f6b762cd9dc63d48979ff7c9e16ba0d7c0e9624b72fa25df1a47bf8a40e19b26dce2acb6b05e7cf15163af39f8e1ead5afeeb2533ae5254b0a8fa
|
data/README.textile
CHANGED
@@ -10,7 +10,7 @@ But the image is not locally stored - it's on another asset server, or in the cl
|
|
10
10
|
|
11
11
|
You don't want to download the entire image to your app server - it could be many tens of kilobytes, or even megabytes just to get this information. For most common image types (GIF, PNG, BMP), the size of the image is simply stored at the start of the file. For JPEG files it's a little bit more complex, but even so you do not need to fetch much of the image to find the size.
|
12
12
|
|
13
|
-
FastImage does this minimal fetch for image types GIF, JPEG, PNG, TIFF and
|
13
|
+
FastImage does this minimal fetch for image types GIF, JPEG, PNG, TIFF, BMP and PSD. And it doesn't rely on installing external libraries such as RMagick (which relies on ImageMagick or GraphicsMagick) or ImageScience (which relies on FreeImage).
|
14
14
|
|
15
15
|
You only need supply the uri, and FastImage will do the rest.
|
16
16
|
|
@@ -54,7 +54,7 @@ bc. gem install fastimage
|
|
54
54
|
|
55
55
|
h4. Rails
|
56
56
|
|
57
|
-
|
57
|
+
Add fastimage to your Gemfile, and bundle.
|
58
58
|
|
59
59
|
Then you're off - just use @FastImage.size()@ and @FastImage.type()@ in your code as in the examples.
|
60
60
|
|
@@ -117,3 +117,14 @@ h2. References
|
|
117
117
|
h2. Licence
|
118
118
|
|
119
119
|
MIT, see file "MIT-LICENSE":MIT-LICENSE
|
120
|
+
|
121
|
+
h2. Contributors
|
122
|
+
|
123
|
+
Pull requests and suggestions are always welcome. Thanks to all the contributors!
|
124
|
+
|
125
|
+
* @felixbuenemann
|
126
|
+
* @speedmax
|
127
|
+
* @sebastianludwig
|
128
|
+
* @benjaminjackson
|
129
|
+
* @muffinista
|
130
|
+
* @marcandre
|
data/lib/fastimage.rb
CHANGED
@@ -5,20 +5,20 @@
|
|
5
5
|
# It does this by using a feature of Net::HTTP that yields strings from the resource being fetched
|
6
6
|
# as soon as the packets arrive.
|
7
7
|
#
|
8
|
-
# No external libraries such as ImageMagick are used here, this is a very lightweight solution to
|
8
|
+
# No external libraries such as ImageMagick are used here, this is a very lightweight solution to
|
9
9
|
# finding image information.
|
10
10
|
#
|
11
|
-
# FastImage knows about GIF, JPEG, BMP, TIFF and
|
11
|
+
# FastImage knows about GIF, JPEG, BMP, TIFF, PNG and PSD files.
|
12
12
|
#
|
13
13
|
# FastImage can also read files from the local filesystem by supplying the path instead of a uri.
|
14
14
|
# In this case FastImage uses the Addressable library to read the file in chunks of 256 bytes until
|
15
15
|
# it has enough. This is possibly a useful bandwidth-saving feature if the file is on a network
|
16
16
|
# attached disk rather than truly local.
|
17
17
|
#
|
18
|
-
#
|
18
|
+
# FastImage will automatically read from any object that responds to :read - for
|
19
19
|
# instance an IO object if that is passed instead of a URI.
|
20
20
|
#
|
21
|
-
#
|
21
|
+
# FastImage will follow up to 4 HTTP redirects to get the image.
|
22
22
|
#
|
23
23
|
# === Examples
|
24
24
|
# require 'fastimage'
|
@@ -43,10 +43,11 @@
|
|
43
43
|
require 'net/https'
|
44
44
|
require 'addressable/uri'
|
45
45
|
require 'fastimage/fbr.rb'
|
46
|
+
require 'delegate'
|
46
47
|
|
47
48
|
class FastImage
|
48
49
|
attr_reader :size, :type
|
49
|
-
|
50
|
+
|
50
51
|
attr_reader :bytes_read
|
51
52
|
|
52
53
|
class FastImageException < StandardError # :nodoc:
|
@@ -63,7 +64,7 @@ class FastImage
|
|
63
64
|
end
|
64
65
|
|
65
66
|
DefaultTimeout = 2
|
66
|
-
|
67
|
+
|
67
68
|
LocalFileChunkSize = 256
|
68
69
|
|
69
70
|
# Returns an array containing the width and height of the image.
|
@@ -141,6 +142,8 @@ class FastImage
|
|
141
142
|
# => :gif
|
142
143
|
# FastImage.type("test/fixtures/test.tiff")
|
143
144
|
# => :tiff
|
145
|
+
# FastImage.type("test/fixtures/test.psd")
|
146
|
+
# => :psd
|
144
147
|
#
|
145
148
|
# === Supported options
|
146
149
|
# [:timeout]
|
@@ -172,12 +175,12 @@ class FastImage
|
|
172
175
|
end
|
173
176
|
end
|
174
177
|
end
|
175
|
-
|
178
|
+
|
176
179
|
uri.rewind if uri.respond_to?(:rewind)
|
177
|
-
|
180
|
+
|
178
181
|
raise SizeNotFound if options[:raise_on_failure] && @property == :size && !@size
|
179
|
-
|
180
|
-
rescue Timeout::Error, SocketError, Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::ECONNRESET,
|
182
|
+
|
183
|
+
rescue Timeout::Error, SocketError, Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::ECONNRESET,
|
181
184
|
ImageFetchFailure, Net::HTTPBadResponse, EOFError, Errno::ENOENT
|
182
185
|
raise ImageFetchFailure if options[:raise_on_failure]
|
183
186
|
rescue NoMethodError # 1.8.7p248 can raise this due to a net/http bug
|
@@ -192,7 +195,7 @@ class FastImage
|
|
192
195
|
raise ImageFetchFailure
|
193
196
|
end
|
194
197
|
end
|
195
|
-
|
198
|
+
|
196
199
|
end
|
197
200
|
|
198
201
|
private
|
@@ -202,7 +205,7 @@ class FastImage
|
|
202
205
|
|
203
206
|
fetch_using_http_from_parsed_uri
|
204
207
|
end
|
205
|
-
|
208
|
+
|
206
209
|
def fetch_using_http_from_parsed_uri
|
207
210
|
setup_http
|
208
211
|
@http.request_get(@parsed_uri.request_uri, 'Accept-Encoding' => 'identity') do |res|
|
@@ -225,14 +228,14 @@ class FastImage
|
|
225
228
|
|
226
229
|
raise ImageFetchFailure unless res.is_a?(Net::HTTPSuccess)
|
227
230
|
|
228
|
-
|
231
|
+
read_fiber = Fiber.new do
|
229
232
|
res.read_body do |str|
|
230
233
|
Fiber.yield str
|
231
234
|
end
|
232
235
|
end
|
233
236
|
|
234
|
-
parse_packets
|
235
|
-
|
237
|
+
parse_packets FiberStream.new(read_fiber)
|
238
|
+
|
236
239
|
break # needed to actively quit out of the fetch
|
237
240
|
end
|
238
241
|
end
|
@@ -261,13 +264,13 @@ class FastImage
|
|
261
264
|
end
|
262
265
|
|
263
266
|
def fetch_using_read(readable)
|
264
|
-
|
267
|
+
read_fiber = Fiber.new do
|
265
268
|
while str = readable.read(LocalFileChunkSize)
|
266
269
|
Fiber.yield str
|
267
270
|
end
|
268
271
|
end
|
269
|
-
|
270
|
-
parse_packets
|
272
|
+
|
273
|
+
parse_packets FiberStream.new(read_fiber)
|
271
274
|
end
|
272
275
|
|
273
276
|
def fetch_using_open_uri
|
@@ -276,16 +279,12 @@ class FastImage
|
|
276
279
|
end
|
277
280
|
end
|
278
281
|
|
279
|
-
def parse_packets
|
280
|
-
@
|
281
|
-
@str.force_encoding("ASCII-8BIT") if has_encoding?
|
282
|
-
@strpos = 0
|
283
|
-
@bytes_read = 0
|
284
|
-
@bytes_delivered = 0
|
282
|
+
def parse_packets(stream)
|
283
|
+
@stream = stream
|
285
284
|
|
286
285
|
begin
|
287
286
|
result = send("parse_#{@property}")
|
288
|
-
if result
|
287
|
+
if result
|
289
288
|
instance_variable_set("@#{@property}", result)
|
290
289
|
else
|
291
290
|
raise CannotParseImage
|
@@ -297,53 +296,60 @@ class FastImage
|
|
297
296
|
|
298
297
|
def parse_size
|
299
298
|
@type = parse_type unless @type
|
300
|
-
@strpos = 0
|
301
|
-
@bytes_delivered = 0
|
302
299
|
send("parse_size_for_#{@type}")
|
303
300
|
end
|
304
301
|
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
302
|
+
module StreamUtil
|
303
|
+
def read_byte
|
304
|
+
read(1).ord
|
305
|
+
end
|
306
|
+
|
307
|
+
def read_int
|
308
|
+
read(2).unpack('n')[0]
|
310
309
|
end
|
311
310
|
end
|
312
311
|
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
new_string = @read_fiber.resume
|
317
|
-
raise CannotParseImage if !new_string
|
312
|
+
class FiberStream
|
313
|
+
include StreamUtil
|
314
|
+
attr_reader :pos
|
318
315
|
|
319
|
-
|
320
|
-
|
321
|
-
|
316
|
+
def initialize(read_fiber)
|
317
|
+
@read_fiber = read_fiber
|
318
|
+
@pos = 0
|
319
|
+
@strpos = 0
|
320
|
+
@str = ''
|
321
|
+
end
|
322
|
+
|
323
|
+
def peek(n)
|
324
|
+
while @strpos + n - 1 >= @str.size
|
325
|
+
unused_str = @str[@strpos..-1]
|
326
|
+
new_string = @read_fiber.resume
|
327
|
+
raise CannotParseImage if !new_string
|
328
|
+
|
329
|
+
# we are dealing with bytes here, so force the encoding
|
330
|
+
new_string.force_encoding("ASCII-8BIT") if String.method_defined? :force_encoding
|
331
|
+
|
332
|
+
@str = unused_str + new_string
|
333
|
+
@strpos = 0
|
322
334
|
end
|
323
335
|
|
324
|
-
@
|
325
|
-
|
326
|
-
@str = unused_str + new_string
|
327
|
-
@strpos = 0
|
336
|
+
result = @str[@strpos..(@strpos + n - 1)]
|
328
337
|
end
|
329
|
-
|
330
|
-
result = @str[@strpos..(@strpos + n - 1)]
|
331
|
-
@strpos += n
|
332
|
-
@bytes_delivered += n
|
333
|
-
result
|
334
|
-
end
|
335
338
|
|
336
|
-
|
337
|
-
|
339
|
+
def read(n)
|
340
|
+
result = peek(n)
|
341
|
+
@strpos += n
|
342
|
+
@pos += n
|
343
|
+
result
|
344
|
+
end
|
338
345
|
end
|
339
346
|
|
340
|
-
|
341
|
-
|
342
|
-
(size_bytes[0] << 8) + size_bytes[1]
|
347
|
+
class IOStream < SimpleDelegator
|
348
|
+
include StreamUtil
|
343
349
|
end
|
344
350
|
|
345
351
|
def parse_type
|
346
|
-
case
|
352
|
+
case @stream.peek(2)
|
347
353
|
when "BM"
|
348
354
|
:bmp
|
349
355
|
when "GI"
|
@@ -352,41 +358,41 @@ class FastImage
|
|
352
358
|
:jpeg
|
353
359
|
when 0x89.chr + "P"
|
354
360
|
:png
|
355
|
-
when "II"
|
356
|
-
:tiff
|
357
|
-
when "MM"
|
361
|
+
when "II", "MM"
|
358
362
|
:tiff
|
363
|
+
when '8B'
|
364
|
+
:psd
|
359
365
|
else
|
360
366
|
raise UnknownImageType
|
361
367
|
end
|
362
368
|
end
|
363
369
|
|
364
370
|
def parse_size_for_gif
|
365
|
-
|
371
|
+
@stream.read(11)[6..10].unpack('SS')
|
366
372
|
end
|
367
373
|
|
368
374
|
def parse_size_for_png
|
369
|
-
|
375
|
+
@stream.read(25)[16..24].unpack('NN')
|
370
376
|
end
|
371
377
|
|
372
378
|
def parse_size_for_jpeg
|
373
379
|
loop do
|
374
380
|
@state = case @state
|
375
381
|
when nil
|
376
|
-
|
382
|
+
@stream.read(2)
|
377
383
|
:started
|
378
384
|
when :started
|
379
|
-
|
385
|
+
@stream.read_byte == 0xFF ? :sof : :started
|
380
386
|
when :sof
|
381
|
-
case
|
387
|
+
case @stream.read_byte
|
382
388
|
when 0xe1 # APP1
|
383
|
-
skip_chars = read_int
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
389
|
+
skip_chars = @stream.read_int - 2
|
390
|
+
data = @stream.read(skip_chars)
|
391
|
+
io = StringIO.new(data)
|
392
|
+
if io.read(4) == "Exif"
|
393
|
+
io.read(2)
|
394
|
+
@exif = Exif.new(IOStream.new(io)) rescue nil
|
388
395
|
end
|
389
|
-
get_chars(skip_chars - (@bytes_delivered - skip_from))
|
390
396
|
:started
|
391
397
|
when 0xe0..0xef
|
392
398
|
:skipframe
|
@@ -398,24 +404,23 @@ class FastImage
|
|
398
404
|
:skipframe
|
399
405
|
end
|
400
406
|
when :skipframe
|
401
|
-
skip_chars = read_int
|
402
|
-
|
407
|
+
skip_chars = @stream.read_int - 2
|
408
|
+
@stream.read(skip_chars)
|
403
409
|
:started
|
404
410
|
when :readsize
|
405
|
-
s =
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
end
|
411
|
+
s = @stream.read(3)
|
412
|
+
height = @stream.read_int
|
413
|
+
width = @stream.read_int
|
414
|
+
width, height = height, width if @exif && @exif.rotated?
|
415
|
+
return [width, height]
|
411
416
|
end
|
412
417
|
end
|
413
418
|
end
|
414
419
|
|
415
420
|
def parse_size_for_bmp
|
416
|
-
d =
|
421
|
+
d = @stream.read(32)[14..28]
|
417
422
|
header = d.unpack("C")[0]
|
418
|
-
|
423
|
+
|
419
424
|
result = if header == 40
|
420
425
|
d[4..-1].unpack('l<l<')
|
421
426
|
else
|
@@ -426,68 +431,84 @@ class FastImage
|
|
426
431
|
[result.first, result.last.abs]
|
427
432
|
end
|
428
433
|
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
when 'MM'
|
435
|
-
@short, @long = 'n', 'N'
|
436
|
-
else
|
437
|
-
raise CannotParseImage
|
434
|
+
class Exif
|
435
|
+
attr_reader :width, :height
|
436
|
+
def initialize(stream)
|
437
|
+
@stream = stream
|
438
|
+
parse_exif
|
438
439
|
end
|
439
|
-
end
|
440
440
|
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
when
|
451
|
-
@
|
452
|
-
when
|
453
|
-
@
|
454
|
-
|
455
|
-
|
456
|
-
return # no need to parse more
|
441
|
+
def rotated?
|
442
|
+
@orientation && @orientation >= 5
|
443
|
+
end
|
444
|
+
|
445
|
+
private
|
446
|
+
|
447
|
+
def get_exif_byte_order
|
448
|
+
byte_order = @stream.read(2)
|
449
|
+
case byte_order
|
450
|
+
when 'II'
|
451
|
+
@short, @long = 'v', 'V'
|
452
|
+
when 'MM'
|
453
|
+
@short, @long = 'n', 'N'
|
454
|
+
else
|
455
|
+
raise CannotParseImage
|
457
456
|
end
|
458
|
-
get_chars(2)
|
459
457
|
end
|
460
458
|
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
459
|
+
def parse_exif_ifd
|
460
|
+
tag_count = @stream.read(2).unpack(@short)[0]
|
461
|
+
tag_count.downto(1) do
|
462
|
+
type = @stream.read(2).unpack(@short)[0]
|
463
|
+
@stream.read(6)
|
464
|
+
data = @stream.read(2).unpack(@short)[0]
|
465
|
+
case type
|
466
|
+
when 0x0100 # image width
|
467
|
+
@width = data
|
468
|
+
when 0x0101 # image height
|
469
|
+
@height = data
|
470
|
+
when 0x0112 # orientation
|
471
|
+
@orientation = data
|
472
|
+
end
|
473
|
+
if @width && @height && @orientation
|
474
|
+
return # no need to parse more
|
475
|
+
end
|
476
|
+
@stream.read(2)
|
477
|
+
end
|
478
|
+
|
479
|
+
next_offset = @stream.read(4).unpack(@long)[0]
|
480
|
+
relative_offset = next_offset - (@stream.pos - @start_byte)
|
481
|
+
if relative_offset >= 0
|
482
|
+
@stream.read(relative_offset)
|
483
|
+
parse_exif_ifd
|
484
|
+
end
|
466
485
|
end
|
467
|
-
end
|
468
486
|
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
487
|
+
def parse_exif
|
488
|
+
@start_byte = @stream.pos
|
489
|
+
|
490
|
+
get_exif_byte_order
|
491
|
+
|
492
|
+
@stream.read(2) # 42
|
475
493
|
|
476
|
-
|
477
|
-
|
494
|
+
offset = @stream.read(4).unpack(@long)[0]
|
495
|
+
@stream.read(offset - 8)
|
496
|
+
|
497
|
+
parse_exif_ifd
|
498
|
+
end
|
478
499
|
|
479
|
-
parse_exif_ifd
|
480
500
|
end
|
481
501
|
|
482
502
|
def parse_size_for_tiff
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
return [@exif_height, @exif_width]
|
503
|
+
exif = Exif.new(@stream)
|
504
|
+
if exif.rotated?
|
505
|
+
[exif.height, exif.width]
|
487
506
|
else
|
488
|
-
|
507
|
+
[exif.width, exif.height]
|
489
508
|
end
|
509
|
+
end
|
490
510
|
|
491
|
-
|
511
|
+
def parse_size_for_psd
|
512
|
+
@stream.read(26).unpack("x14NN").reverse
|
492
513
|
end
|
493
514
|
end
|
Binary file
|
Binary file
|
data/test/test.rb
CHANGED
@@ -18,8 +18,10 @@ GoodFixtures = {
|
|
18
18
|
"test.png"=>[:png, [30, 20]],
|
19
19
|
"test2.jpg"=>[:jpeg, [250, 188]],
|
20
20
|
"test3.jpg"=>[:jpeg, [630, 367]],
|
21
|
+
"test4.jpg"=>[:jpeg, [1485, 1299]],
|
21
22
|
"test.tiff"=>[:tiff, [85, 67]],
|
22
23
|
"test2.tiff"=>[:tiff, [333, 225]],
|
24
|
+
"test.psd"=>[:psd, [17, 32]],
|
23
25
|
"exif_orientation.jpg"=>[:jpeg, [2448, 3264]],
|
24
26
|
"infinite.jpg"=>[:jpeg, [160,240]]
|
25
27
|
}
|
@@ -59,13 +61,13 @@ class FastImageTest < Test::Unit::TestCase
|
|
59
61
|
GoodFixtures.each do |fn, info|
|
60
62
|
assert_equal info[1], FastImage.size(TestUrl + fn)
|
61
63
|
assert_equal info[1], FastImage.size(TestUrl + fn, :raise_on_failure=>true)
|
62
|
-
end
|
64
|
+
end
|
63
65
|
end
|
64
66
|
|
65
67
|
def test_should_return_nil_on_fetch_failure
|
66
68
|
assert_nil FastImage.size(TestUrl + "does_not_exist")
|
67
69
|
end
|
68
|
-
|
70
|
+
|
69
71
|
def test_should_return_nil_for_faulty_jpeg_where_size_cannot_be_found
|
70
72
|
assert_nil FastImage.size(TestUrl + "faulty.jpg")
|
71
73
|
end
|
@@ -73,11 +75,11 @@ class FastImageTest < Test::Unit::TestCase
|
|
73
75
|
def test_should_return_nil_when_image_type_not_known
|
74
76
|
assert_nil FastImage.size(TestUrl + "test.ico")
|
75
77
|
end
|
76
|
-
|
78
|
+
|
77
79
|
def test_should_return_nil_if_timeout_occurs
|
78
80
|
assert_nil FastImage.size("http://example.com/does_not_exist", :timeout=>0.001)
|
79
81
|
end
|
80
|
-
|
82
|
+
|
81
83
|
def test_should_raise_when_asked_to_when_size_cannot_be_found
|
82
84
|
assert_raises(FastImage::SizeNotFound) do
|
83
85
|
FastImage.size(TestUrl + "faulty.jpg", :raise_on_failure=>true)
|
@@ -101,17 +103,17 @@ class FastImageTest < Test::Unit::TestCase
|
|
101
103
|
FastImage.size(TestUrl + "test.ico", :raise_on_failure=>true)
|
102
104
|
end
|
103
105
|
end
|
104
|
-
|
106
|
+
|
105
107
|
def test_should_report_type_correctly_for_local_files
|
106
108
|
GoodFixtures.each do |fn, info|
|
107
109
|
assert_equal info[0], FastImage.type(File.join(FixturePath, fn))
|
108
|
-
end
|
110
|
+
end
|
109
111
|
end
|
110
|
-
|
112
|
+
|
111
113
|
def test_should_report_size_correctly_for_local_files
|
112
114
|
GoodFixtures.each do |fn, info|
|
113
115
|
assert_equal info[1], FastImage.size(File.join(FixturePath, fn))
|
114
|
-
end
|
116
|
+
end
|
115
117
|
end
|
116
118
|
|
117
119
|
def test_should_report_type_correctly_for_ios
|
@@ -121,7 +123,7 @@ class FastImageTest < Test::Unit::TestCase
|
|
121
123
|
end
|
122
124
|
end
|
123
125
|
end
|
124
|
-
|
126
|
+
|
125
127
|
def test_should_report_size_correctly_for_ios
|
126
128
|
GoodFixtures.each do |fn, info|
|
127
129
|
File.open(File.join(FixturePath, fn), "r") do |io|
|
@@ -129,7 +131,7 @@ class FastImageTest < Test::Unit::TestCase
|
|
129
131
|
end
|
130
132
|
end
|
131
133
|
end
|
132
|
-
|
134
|
+
|
133
135
|
def test_should_report_size_correctly_on_io_object_twice
|
134
136
|
GoodFixtures.each do |fn, info|
|
135
137
|
File.open(File.join(FixturePath, fn), "r") do |io|
|
@@ -144,11 +146,11 @@ class FastImageTest < Test::Unit::TestCase
|
|
144
146
|
assert_equal GoodFixtures["test.bmp"][1], FastImage.size(File.join("fixtures", "folder with spaces", "test.bmp"))
|
145
147
|
end
|
146
148
|
end
|
147
|
-
|
149
|
+
|
148
150
|
def test_should_return_nil_on_fetch_failure_for_local_path
|
149
151
|
assert_nil FastImage.size("does_not_exist")
|
150
152
|
end
|
151
|
-
|
153
|
+
|
152
154
|
def test_should_return_nil_for_faulty_jpeg_where_size_cannot_be_found_for_local_file
|
153
155
|
assert_nil FastImage.size(File.join(FixturePath, "faulty.jpg"))
|
154
156
|
end
|
@@ -156,13 +158,13 @@ class FastImageTest < Test::Unit::TestCase
|
|
156
158
|
def test_should_return_nil_when_image_type_not_known_for_local_file
|
157
159
|
assert_nil FastImage.size(File.join(FixturePath, "test.ico"))
|
158
160
|
end
|
159
|
-
|
161
|
+
|
160
162
|
def test_should_raise_when_asked_to_when_size_cannot_be_found_for_local_file
|
161
163
|
assert_raises(FastImage::SizeNotFound) do
|
162
164
|
FastImage.size(File.join(FixturePath, "faulty.jpg"), :raise_on_failure=>true)
|
163
165
|
end
|
164
166
|
end
|
165
|
-
|
167
|
+
|
166
168
|
def test_should_handle_permanent_redirect
|
167
169
|
url = "http://example.com/foo.jpeg"
|
168
170
|
register_redirect(url, TestUrl + GoodFixtures.keys.first)
|
@@ -189,7 +191,7 @@ class FastImageTest < Test::Unit::TestCase
|
|
189
191
|
FastImage.size(first_url, :raise_on_failure=>true)
|
190
192
|
end
|
191
193
|
end
|
192
|
-
|
194
|
+
|
193
195
|
def test_should_handle_permanent_redirect_with_relative_url
|
194
196
|
url = "http://example.nowhere/foo.jpeg"
|
195
197
|
register_redirect(url, "/" + GoodFixtures.keys.first)
|
@@ -201,7 +203,7 @@ class FastImageTest < Test::Unit::TestCase
|
|
201
203
|
resp['Location'] = to
|
202
204
|
FakeWeb.register_uri(:get, from, :response=>resp)
|
203
205
|
end
|
204
|
-
|
206
|
+
|
205
207
|
def test_should_fetch_info_of_large_image_faster_than_downloading_the_whole_thing
|
206
208
|
time = Time.now
|
207
209
|
size = FastImage.size(LargeImage)
|
@@ -214,7 +216,7 @@ class FastImageTest < Test::Unit::TestCase
|
|
214
216
|
assert type_time - time < LargeImageFetchLimit
|
215
217
|
assert_equal LargeImageInfo[0], type
|
216
218
|
end
|
217
|
-
|
219
|
+
|
218
220
|
# This test doesn't actually test the proxy function, but at least
|
219
221
|
# it excercises the code. You could put anything in the http_proxy and it would still pass.
|
220
222
|
# Any ideas on how to actually test this?
|
@@ -226,9 +228,9 @@ class FastImageTest < Test::Unit::TestCase
|
|
226
228
|
ENV['http_proxy'] = nil
|
227
229
|
assert_equal actual_size, size
|
228
230
|
end
|
229
|
-
|
231
|
+
|
230
232
|
def test_should_handle_https_image
|
231
233
|
size = FastImage.size(HTTPSImage)
|
232
|
-
assert_equal HTTPSImageInfo[1], size
|
234
|
+
assert_equal HTTPSImageInfo[1], size
|
233
235
|
end
|
234
236
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fastimage
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stephen Sykes
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2014-01-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: addressable
|
@@ -92,12 +92,14 @@ files:
|
|
92
92
|
- test/fixtures/test.png
|
93
93
|
- test/fixtures/test2.jpg
|
94
94
|
- test/fixtures/test3.jpg
|
95
|
+
- test/fixtures/test4.jpg
|
95
96
|
- test/fixtures/test.tiff
|
96
97
|
- test/fixtures/test2.tiff
|
97
98
|
- test/fixtures/exif_orientation.jpg
|
98
99
|
- test/fixtures/infinite.jpg
|
99
100
|
- test/fixtures/folder with spaces/test.bmp
|
100
101
|
- test/test.rb
|
102
|
+
- test/fixtures/test.psd
|
101
103
|
homepage: http://github.com/sdsykes/fastimage
|
102
104
|
licenses:
|
103
105
|
- MIT
|