Class: ImageSpec::Parser::JPEG

Inherits:
Object
  • Object
show all
Defined in:
lib/image_spec/parser/jpeg.rb

Constant Summary collapse

CONTENT_TYPE =
'image/jpeg'
TYPE_JFIF =
Regexp.new '^\xff\xd8\xff\xe0\x00\x10JFIF', nil, 'n'
TYPE_EXIF =
Regexp.new '^\xff\xd8\xff\xe1(.*){2}Exif', nil, 'n'

Class Method Summary collapse

Class Method Details

.attributes(stream) ⇒ Object



8
9
10
11
# File 'lib/image_spec/parser/jpeg.rb', line 8

def self.attributes(stream)
  width, height = dimensions(stream)
  {:width => width, :height => height, :content_type => CONTENT_TYPE, :dimensions => [width, height], :file_size => size(stream)}
end

.detected?(stream) ⇒ Boolean

Returns:

  • (Boolean)


13
14
15
16
17
18
19
# File 'lib/image_spec/parser/jpeg.rb', line 13

def self.detected?(stream)
  stream.rewind
  case stream.read(10)
  when TYPE_JFIF, TYPE_EXIF then true
  else false
  end
end

.dimensions(stream) ⇒ Object

Raises:



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/image_spec/parser/jpeg.rb', line 21

def self.dimensions(stream)
  stream.rewind
  raise ImageSpec::Error, 'malformed JPEG' unless stream.readbyte.chr == "\xFF" && stream.readbyte.chr == "\xD8" # SOI

  class << stream
    def readint
      (readbyte.ord << 8) + readbyte.ord
    end

    def readframe
      read(readint - 2)
    end

    def readsof
      [readint, readbyte.chr, readint, readint, readbyte.chr]
    end

    def next
      c = readbyte.chr while c != "\xFF"
      c = readbyte.chr while c == "\xFF"
      c
    end
  end

  while marker = stream.next
    case marker
    when "\xC0".."\xC3", "\xC5".."\xC7", "\xC9".."\xCB", "\xCD".."\xCF"
      length, bits, height, width, components = stream.readsof
      raise ImageSpec::Error, 'malformed JPEG' unless length == 8 + components[0].ord * 3
      return [width, height]
    when "\xD9", "\xDA"
      break
    when "\xFE"
      @comment = stream.readframe
    else
      stream.readframe
    end
  end
end

.size(stream) ⇒ Object



61
62
63
# File 'lib/image_spec/parser/jpeg.rb', line 61

def self.size(stream)
  stream.size
end