fastimage 2.1.7 → 2.2.0
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.
- checksums.yaml +4 -4
- data/README.textile +1 -1
- data/lib/fastimage.rb +115 -7
- metadata +4 -4
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 53c0966ef5216c189e2950b1ad36c106777175f0d4dca9851abd34472fd9cb61
         | 
| 4 | 
            +
              data.tar.gz: 29f5a6bc03623e184166e7f9c5e8c4379011b301904d4c690037d5b7b0ba0b33
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 28e8ec4debe6c2c477da19cafb1ad41e5de4d809136bd86621ae128372c32c1259abea833856f73dfcfe8ef3444bc5e1a148f91b52ee02d3292235c4d95fc542
         | 
| 7 | 
            +
              data.tar.gz: ba8b4c6bb42146387b1a8af718fbbaf74a9a94532ee5adce082ff676095dad5d5e0eb613f1ec41d7729709847195fa81c4614f2d9d510d6c7def67f8970f168e
         | 
    
        data/README.textile
    CHANGED
    
    | @@ -1,5 +1,5 @@ | |
| 1 1 | 
             
            !https://img.shields.io/gem/dt/fastimage.svg!:https://rubygems.org/gems/fastimage
         | 
| 2 | 
            -
            !https://travis-ci.org/sdsykes/fastimage. | 
| 2 | 
            +
            !https://travis-ci.org/sdsykes/fastimage.svg?branch=master!:https://travis-ci.org/sdsykes/fastimage
         | 
| 3 3 |  | 
| 4 4 | 
             
            h1. FastImage
         | 
| 5 5 |  | 
    
        data/lib/fastimage.rb
    CHANGED
    
    | @@ -70,7 +70,7 @@ if RUBY_VERSION < "2.2" | |
| 70 70 | 
             
            end
         | 
| 71 71 |  | 
| 72 72 | 
             
            class FastImage
         | 
| 73 | 
            -
              attr_reader :size, :type, :content_length, :orientation
         | 
| 73 | 
            +
              attr_reader :size, :type, :content_length, :orientation, :animated
         | 
| 74 74 |  | 
| 75 75 | 
             
              attr_reader :bytes_read
         | 
| 76 76 |  | 
| @@ -179,6 +179,34 @@ class FastImage | |
| 179 179 | 
             
                new(uri, options.merge(:type_only=>true)).type
         | 
| 180 180 | 
             
              end
         | 
| 181 181 |  | 
| 182 | 
            +
              # Returns a boolean value indicating the image is animated.
         | 
| 183 | 
            +
              # It will return nil if the image could not be fetched, or if the image type was not recognised.
         | 
| 184 | 
            +
              #
         | 
| 185 | 
            +
              # By default there is a timeout of 2 seconds for opening and reading from a remote server.
         | 
| 186 | 
            +
              # This can be changed by passing a :timeout => number_of_seconds in the options.
         | 
| 187 | 
            +
              #
         | 
| 188 | 
            +
              # If you wish FastImage to raise if it cannot find the type of the image for any reason, then pass
         | 
| 189 | 
            +
              # :raise_on_failure => true in the options.
         | 
| 190 | 
            +
              #
         | 
| 191 | 
            +
              # === Example
         | 
| 192 | 
            +
              #
         | 
| 193 | 
            +
              #   require 'fastimage'
         | 
| 194 | 
            +
              #
         | 
| 195 | 
            +
              #   FastImage.animated?("test/fixtures/test.gif")
         | 
| 196 | 
            +
              #   => false
         | 
| 197 | 
            +
              #   FastImage.animated?("test/fixtures/animated.gif")
         | 
| 198 | 
            +
              #   => true
         | 
| 199 | 
            +
              #
         | 
| 200 | 
            +
              # === Supported options
         | 
| 201 | 
            +
              # [:timeout]
         | 
| 202 | 
            +
              #   Overrides the default timeout of 2 seconds.  Applies both to reading from and opening the http connection.
         | 
| 203 | 
            +
              # [:raise_on_failure]
         | 
| 204 | 
            +
              #   If set to true causes an exception to be raised if the image type cannot be found for any reason.
         | 
| 205 | 
            +
              #
         | 
| 206 | 
            +
              def self.animated?(uri, options={})
         | 
| 207 | 
            +
                new(uri, options.merge(:animated_only=>true)).animated
         | 
| 208 | 
            +
              end
         | 
| 209 | 
            +
             | 
| 182 210 | 
             
              def initialize(uri, options={})
         | 
| 183 211 | 
             
                @uri = uri
         | 
| 184 212 | 
             
                @options = {
         | 
| @@ -189,7 +217,13 @@ class FastImage | |
| 189 217 | 
             
                  :http_header      => {}
         | 
| 190 218 | 
             
                }.merge(options)
         | 
| 191 219 |  | 
| 192 | 
            -
                @property = @options[: | 
| 220 | 
            +
                @property = if @options[:animated_only]
         | 
| 221 | 
            +
                  :animated
         | 
| 222 | 
            +
                elsif @options[:type_only]
         | 
| 223 | 
            +
                  :type
         | 
| 224 | 
            +
                else
         | 
| 225 | 
            +
                  :size
         | 
| 226 | 
            +
                end
         | 
| 193 227 |  | 
| 194 228 | 
             
                @type, @state = nil
         | 
| 195 229 |  | 
| @@ -248,7 +282,7 @@ class FastImage | |
| 248 282 | 
             
                begin
         | 
| 249 283 | 
             
                  URI(location)
         | 
| 250 284 | 
             
                rescue URI::InvalidURIError
         | 
| 251 | 
            -
                  URI.escape(location)
         | 
| 285 | 
            +
                  ::URI::DEFAULT_PARSER.escape(location)
         | 
| 252 286 | 
             
                else
         | 
| 253 287 | 
             
                  location
         | 
| 254 288 | 
             
                end
         | 
| @@ -262,7 +296,10 @@ class FastImage | |
| 262 296 | 
             
                  if res.is_a?(Net::HTTPRedirection) && @redirect_count < 4
         | 
| 263 297 | 
             
                    @redirect_count += 1
         | 
| 264 298 | 
             
                    begin
         | 
| 265 | 
            -
                       | 
| 299 | 
            +
                      location = res['Location']
         | 
| 300 | 
            +
                      raise ImageFetchFailure if location.nil? || location.empty?
         | 
| 301 | 
            +
             | 
| 302 | 
            +
                      @parsed_uri = URI.join(@parsed_uri, escaped_location(location))
         | 
| 266 303 | 
             
                    rescue URI::InvalidURIError
         | 
| 267 304 | 
             
                    else
         | 
| 268 305 | 
             
                      fetch_using_http_from_parsed_uri
         | 
| @@ -369,7 +406,7 @@ class FastImage | |
| 369 406 |  | 
| 370 407 | 
             
                begin
         | 
| 371 408 | 
             
                  result = send("parse_#{@property}")
         | 
| 372 | 
            -
                  if result
         | 
| 409 | 
            +
                  if result != nil
         | 
| 373 410 | 
             
                    # extract exif orientation if it was found
         | 
| 374 411 | 
             
                    if @property == :size && result.size == 3
         | 
| 375 412 | 
             
                      @orientation = result.pop
         | 
| @@ -391,6 +428,11 @@ class FastImage | |
| 391 428 | 
             
                send("parse_size_for_#{@type}")
         | 
| 392 429 | 
             
              end
         | 
| 393 430 |  | 
| 431 | 
            +
              def parse_animated
         | 
| 432 | 
            +
                @type = parse_type unless @type
         | 
| 433 | 
            +
                @type == :gif ? send("parse_animated_for_#{@type}") : nil
         | 
| 434 | 
            +
              end
         | 
| 435 | 
            +
             | 
| 394 436 | 
             
              def fetch_using_base64(uri)
         | 
| 395 437 | 
             
                data = uri.split(',')[1]
         | 
| 396 438 | 
             
                decoded = Base64.decode64(data)
         | 
| @@ -502,7 +544,7 @@ class FastImage | |
| 502 544 | 
             
                when "RI"
         | 
| 503 545 | 
             
                  :webp if @stream.peek(12)[8..11] == "WEBP"
         | 
| 504 546 | 
             
                when "<s"
         | 
| 505 | 
            -
                  :svg
         | 
| 547 | 
            +
                  :svg if @stream.peek(4) == "<svg"
         | 
| 506 548 | 
             
                when /<[?!]/
         | 
| 507 549 | 
             
                  # Peek 10 more chars each time, and if end of file is reached just raise
         | 
| 508 550 | 
             
                  # unknown. We assume the <svg tag cannot be within 10 chars of the end of
         | 
| @@ -524,8 +566,69 @@ class FastImage | |
| 524 566 | 
             
              end
         | 
| 525 567 | 
             
              alias_method :parse_size_for_cur, :parse_size_for_ico
         | 
| 526 568 |  | 
| 569 | 
            +
              class Gif # :nodoc:
         | 
| 570 | 
            +
                def initialize(stream)
         | 
| 571 | 
            +
                  @stream = stream
         | 
| 572 | 
            +
                end
         | 
| 573 | 
            +
             | 
| 574 | 
            +
                def width_and_height
         | 
| 575 | 
            +
                  @stream.read(11)[6..10].unpack('SS')
         | 
| 576 | 
            +
                end
         | 
| 577 | 
            +
             | 
| 578 | 
            +
                # Checks if a delay between frames exists and if it does, then the GIFs is
         | 
| 579 | 
            +
                # animated
         | 
| 580 | 
            +
                def animated?
         | 
| 581 | 
            +
                  delay = 0
         | 
| 582 | 
            +
             | 
| 583 | 
            +
                  @stream.read(10) # "GIF" + version (3) + width (2) + height (2)
         | 
| 584 | 
            +
             | 
| 585 | 
            +
                  fields = @stream.read(3).unpack("C")[0] # fields (1) + bg color (1) + pixel ratio (1)
         | 
| 586 | 
            +
             | 
| 587 | 
            +
                  # Skip Global Color Table if it exists
         | 
| 588 | 
            +
                  if fields & 0x80
         | 
| 589 | 
            +
                    # 2 * (depth + 1) colors, each occupying 3 bytes (RGB)
         | 
| 590 | 
            +
                    @stream.skip(3 * 2 ** ((fields & 0x7) + 1))
         | 
| 591 | 
            +
                  end
         | 
| 592 | 
            +
             | 
| 593 | 
            +
                  loop do
         | 
| 594 | 
            +
                    block_type = @stream.read(1).unpack("C")[0]
         | 
| 595 | 
            +
                    if block_type == 0x21
         | 
| 596 | 
            +
                      extension_type = @stream.read(1).unpack("C")[0]
         | 
| 597 | 
            +
                      size = @stream.read(1).unpack("C")[0]
         | 
| 598 | 
            +
                      if extension_type == 0xF9
         | 
| 599 | 
            +
                        delay = @stream.read(4).unpack("CSC")[1] # fields (1) + delay (2) + transparent index (1)
         | 
| 600 | 
            +
                        break
         | 
| 601 | 
            +
                      elsif extension_type == 0xFF
         | 
| 602 | 
            +
                        @stream.skip(size) # application ID (8) + version (3)
         | 
| 603 | 
            +
                      else
         | 
| 604 | 
            +
                        return # unrecognized extension
         | 
| 605 | 
            +
                      end
         | 
| 606 | 
            +
                      skip_sub_blocks
         | 
| 607 | 
            +
                    else
         | 
| 608 | 
            +
                      return # unrecognized block
         | 
| 609 | 
            +
                    end
         | 
| 610 | 
            +
                  end
         | 
| 611 | 
            +
             | 
| 612 | 
            +
                  delay > 0
         | 
| 613 | 
            +
                end
         | 
| 614 | 
            +
             | 
| 615 | 
            +
                private
         | 
| 616 | 
            +
             | 
| 617 | 
            +
                def skip_sub_blocks
         | 
| 618 | 
            +
                  loop do
         | 
| 619 | 
            +
                    size = @stream.read(1).unpack("C")[0]
         | 
| 620 | 
            +
                    if size == 0
         | 
| 621 | 
            +
                      break
         | 
| 622 | 
            +
                    else
         | 
| 623 | 
            +
                      @stream.skip(size)
         | 
| 624 | 
            +
                    end
         | 
| 625 | 
            +
                  end
         | 
| 626 | 
            +
                end
         | 
| 627 | 
            +
              end
         | 
| 628 | 
            +
             | 
| 527 629 | 
             
              def parse_size_for_gif
         | 
| 528 | 
            -
                @stream | 
| 630 | 
            +
                gif = Gif.new(@stream)
         | 
| 631 | 
            +
                gif.width_and_height
         | 
| 529 632 | 
             
              end
         | 
| 530 633 |  | 
| 531 634 | 
             
              def parse_size_for_png
         | 
| @@ -785,4 +888,9 @@ class FastImage | |
| 785 888 | 
             
                svg = Svg.new(@stream)
         | 
| 786 889 | 
             
                svg.width_and_height
         | 
| 787 890 | 
             
              end
         | 
| 891 | 
            +
             | 
| 892 | 
            +
              def parse_animated_for_gif
         | 
| 893 | 
            +
                gif = Gif.new(@stream)
         | 
| 894 | 
            +
                gif.animated?
         | 
| 895 | 
            +
              end
         | 
| 788 896 | 
             
            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: 2. | 
| 4 | 
            +
              version: 2.2.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: 2020-07-23 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: fakeweb-fi
         | 
| @@ -28,14 +28,14 @@ dependencies: | |
| 28 28 | 
             
              name: rake
         | 
| 29 29 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 30 30 | 
             
                requirements:
         | 
| 31 | 
            -
                - - " | 
| 31 | 
            +
                - - ">="
         | 
| 32 32 | 
             
                  - !ruby/object:Gem::Version
         | 
| 33 33 | 
             
                    version: '10.5'
         | 
| 34 34 | 
             
              type: :development
         | 
| 35 35 | 
             
              prerelease: false
         | 
| 36 36 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 37 37 | 
             
                requirements:
         | 
| 38 | 
            -
                - - " | 
| 38 | 
            +
                - - ">="
         | 
| 39 39 | 
             
                  - !ruby/object:Gem::Version
         | 
| 40 40 | 
             
                    version: '10.5'
         | 
| 41 41 | 
             
            - !ruby/object:Gem::Dependency
         |