# File lib/ascii85.rb, line 124
  def self.decode(str)

    input = str.to_s

    opening_delim = '<~'
    closing_delim = '~>'

    # Make sure the delimiter strings have the correct encoding.
    #
    # Although I don't think it likely, this may raise encoding
    # errors if an especially exotic input encoding is introduced.
    # As of Ruby 1.9.2 all non-dummy encodings work fine though.
    #
    if opening_delim.respond_to?(:encode!)
      opening_delim.encode!(input.encoding)
      closing_delim.encode!(input.encoding)
    end

    # Get the positions of the opening/closing delimiters. If there is
    # no pair of opening/closing delimiters, return the empty string.
    (start_pos = input.index(opening_delim))                or return ''
    (end_pos   = input.index(closing_delim, start_pos + 2)) or return ''

    # Get the string inside the delimiter-pair
    input = input[(start_pos + 2)...end_pos]

    # Decode
    word   = 0
    count  = 0
    result = []

    input.each_byte do |c|

      case c.chr
      when " ", "\t", "\r", "\n", "\f", "\0"
        # Ignore whitespace
        next

      when 'z'
        if count == 0
          # Expand z to 0-word
          result << 0
        else
          raise(Ascii85::DecodingError, "Found 'z' inside Ascii85 5-tuple")
        end

      when '!'..'u'
        # Decode 5 characters into a 4-byte word
        word  += (c - 33) * 85**(4 - count)
        count += 1

        if count == 5

          if word > 0xffffffff
            raise(Ascii85::DecodingError,
                  "Invalid Ascii85 5-tuple (#{word} >= 2**32)")
          end

          result << word

          word  = 0
          count = 0
        end

      else
        raise(Ascii85::DecodingError,
              "Illegal character inside Ascii85: #{c.chr.dump}")
      end

    end

    # Convert result into a String
    result = result.pack('N*')

    if count > 0
      # Finish last, partially decoded 32-bit-word

      if count == 1
        raise(Ascii85::DecodingError,
              "Last 5-tuple consists of single character")
      end

      count -= 1
      word  += 85**(4 - count)

      result << ((word >> 24) & 255).chr if count >= 1
      result << ((word >> 16) & 255).chr if count >= 2
      result << ((word >>  8) & 255).chr if count == 3
    end

    return result
  end