Class: Branding::PNG

Inherits:
Object
  • Object
show all
Defined in:
lib/branding/png.rb

Overview

This is a simple PNG decoder, inspired and adapted from ChunkyPNG

Defined Under Namespace

Classes: Filter, Imagedata

Constant Summary collapse

SIGNATURE =
[137, 80, 78, 71, 13, 10, 26, 10].pack('C8').force_encoding('BINARY')

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(io) ⇒ PNG

Returns a new instance of PNG.



159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/branding/png.rb', line 159

def initialize(io)
  signature = io.read(SIGNATURE.length)
  raise 'Signature mismatch' unless signature == SIGNATURE

  @data = ''

  until io.eof?
    type, content = read_chunk(io)

    case type
    when 'IHDR'
      fields = content.unpack('NNC5')
      @width, @height, @depth, @color, @compression, @filtering, @interlace = fields

    when 'IDAT'
      @data << content
    end
  end

  unless depth == 8
    raise NotImplementedError, 'only supporting 8bit color depth'
  end

  unless color == 2 || color == 6
    raise NotImplementedError, 'only supporting true color, with or without alpha'
  end

  unless filtering == 0
    raise NotImplementedError, 'does not supporting filtering'
  end

  unless compression == 0
    raise NotImplementedError, 'only supporting deflate compression'
  end
end

Instance Attribute Details

#colorObject (readonly)

Returns the value of attribute color.



9
10
11
# File 'lib/branding/png.rb', line 9

def color
  @color
end

#compressionObject (readonly)

Returns the value of attribute compression.



9
10
11
# File 'lib/branding/png.rb', line 9

def compression
  @compression
end

#depthObject (readonly)

Returns the value of attribute depth.



9
10
11
# File 'lib/branding/png.rb', line 9

def depth
  @depth
end

#filteringObject (readonly)

Returns the value of attribute filtering.



9
10
11
# File 'lib/branding/png.rb', line 9

def filtering
  @filtering
end

#heightObject (readonly)

Returns the value of attribute height.



9
10
11
# File 'lib/branding/png.rb', line 9

def height
  @height
end

#interlaceObject (readonly)

Returns the value of attribute interlace.



9
10
11
# File 'lib/branding/png.rb', line 9

def interlace
  @interlace
end

#widthObject (readonly)

Returns the value of attribute width.



9
10
11
# File 'lib/branding/png.rb', line 9

def width
  @width
end

Class Method Details

.from_file(path) ⇒ Object



155
156
157
# File 'lib/branding/png.rb', line 155

def self.from_file(path)
  new(File.open(path, 'rb'))
end

Instance Method Details

#color_channelsObject

the number of color channels. Not the PNG “color mode”



205
206
207
# File 'lib/branding/png.rb', line 205

def color_channels
  color == 2 ? 3 : 4
end

#pixelsObject



195
196
197
198
199
200
201
# File 'lib/branding/png.rb', line 195

def pixels
  if block_given?
    imagedata.each_pixel
  else
    imagedata.enum_for(:each_pixel).to_a
  end
end