Skip to content

Instantly share code, notes, and snippets.

@rummelonp
Created February 3, 2012 17:38
Show Gist options
  • Save rummelonp/1731319 to your computer and use it in GitHub Desktop.
Save rummelonp/1731319 to your computer and use it in GitHub Desktop.
GIF 画像解析するやつ(書きかけ)
# -*- coding: utf-8 -*-
class GIF
class ImplementationError < StandardError
end
def self.parse(arg)
if arg.is_a? File
new(arg).parse
elsif File.exists?(arg)
new(open(arg, 'rb')).parse
else
raise Errno::ENOENT
end
end
HEADER = [
:signature,
:version,
:logical_screen_width,
:logical_screen_height,
:global_color_table_flag,
:color_resolution,
:sort_flag,
:size_of_global_color_table,
:background_color_index,
:pixel_aspect_ratio,
:global_color_table,
]
attr_accessor *HEADER
def initialize(file)
@file = file
@file.singleton_class.send(:include, IOExtension)
end
def parse
parse_header
self
end
def parse_header
@file.seek(0, IO::SEEK_SET)
@signature,
@version,
@logical_screen_width,
@logical_screen_height,
bit,
@background_color_index,
@pixel_aspect_ratio = @file.unpack('a3a3vvCCC')
@global_color_table_flag = bit & 0b10000000 != 0
@color_resolution = ((bit >> 4) & 0b0111) + 1
@sort_flag = bit & 0b1000 != 0
@size_of_global_color_table = ((bit & 0b00000111) + 1) ** 2
if @global_color_table_flag
@global_color_table = (0..@size_of_global_color_table).map { @file.unpack('CCC') }
end
end
module IOExtension
def unpack(template)
read(unpack_size(template)).unpack(template)
end
private
def unpack_size(template)
template.scan(/\w\d+|\w/).inject(0) do |total, value|
format = value.slice(0, 1)
size = (value.slice(1) || 1).to_i
case format.to_sym
when :a, :C
total + 1 * size
when :v
total + 2 * size
else
raise ImplementationError
end
end
end
end
end
if $0 == __FILE__
file = ARGV.shift
gif = GIF.parse(file)
p gif
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment