Added gif-to-c converter.
This commit is contained in:
parent
24f6c7e798
commit
1a4873aed6
138
tools/gif2c.rb
Normal file
138
tools/gif2c.rb
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
#!/usr/bin/env ruby
|
||||||
|
require 'rubygems'
|
||||||
|
require 'rmagick'
|
||||||
|
require 'pp'
|
||||||
|
|
||||||
|
###
|
||||||
|
# Converts a gif file to c code to enable displaying animations.
|
||||||
|
#
|
||||||
|
# The data format is described in animations.h
|
||||||
|
###
|
||||||
|
|
||||||
|
def compress(data, use_cutoff=true)
|
||||||
|
cutoff = 3
|
||||||
|
escape = 255
|
||||||
|
last = data[0]
|
||||||
|
result = []
|
||||||
|
count = 0
|
||||||
|
data.each do |x|
|
||||||
|
if x == last
|
||||||
|
count += 1
|
||||||
|
else
|
||||||
|
if use_cutoff
|
||||||
|
if count <= cutoff
|
||||||
|
count.times { result << last }
|
||||||
|
else
|
||||||
|
result << escape << count << last
|
||||||
|
end
|
||||||
|
else
|
||||||
|
result << count << last
|
||||||
|
end
|
||||||
|
count = 1
|
||||||
|
last = x
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if use_cutoff
|
||||||
|
if count < cutoff
|
||||||
|
count.times { result << last }
|
||||||
|
else
|
||||||
|
result << escape << count << last
|
||||||
|
end
|
||||||
|
else
|
||||||
|
result << count << last
|
||||||
|
end
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
unless ARGV[0] && ARGV[1]
|
||||||
|
puts "Usage:"
|
||||||
|
puts "#{$0} <gif_file> <variable_name>"
|
||||||
|
puts "e.g. '#{$0} mario.gif mario'"
|
||||||
|
puts
|
||||||
|
puts "Resulting data format is described in animations.h"
|
||||||
|
exit 1
|
||||||
|
end
|
||||||
|
|
||||||
|
image_file=ARGV[0]
|
||||||
|
name=ARGV[1]
|
||||||
|
frames = Magick::ImageList.new(image_file)
|
||||||
|
|
||||||
|
puts "Found #{frames.count} frames."
|
||||||
|
|
||||||
|
print "Getting colors..."
|
||||||
|
colors = []
|
||||||
|
frames.each do |frame|
|
||||||
|
frame.columns.times do |x|
|
||||||
|
frame.rows.times do |y|
|
||||||
|
color = frame.pixel_color(x, y).to_color(Magick::AllCompliance, true, 8, true)
|
||||||
|
colors << color
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
colors = colors.uniq
|
||||||
|
|
||||||
|
puts " Found #{colors.count} colors."
|
||||||
|
|
||||||
|
transparent = colors.select{|c| c.end_with? "00"}
|
||||||
|
|
||||||
|
puts "#{transparent.count} color(s) being transparent."
|
||||||
|
|
||||||
|
colors = (["#00000012", "#000000FF"] + (colors - transparent)).uniq
|
||||||
|
puts "Using #{colors.count} colors."
|
||||||
|
raise "Number of colors has to be 255 or less!" if colors.count>255
|
||||||
|
|
||||||
|
puts
|
||||||
|
puts
|
||||||
|
puts "uint32_t #{name}_colors[] = {#{colors.map{|c| "0x" + c[1, 6]}.join(", ")}};"
|
||||||
|
|
||||||
|
p_frame = nil
|
||||||
|
frames_data = []
|
||||||
|
frames.each_with_index do |frame, index|
|
||||||
|
data = []
|
||||||
|
if index==0 # first frame
|
||||||
|
frame.rows.times do |y|
|
||||||
|
frame.columns.times do |x|
|
||||||
|
color = frame.pixel_color(x, y).to_color(Magick::AllCompliance, true, 8, true)
|
||||||
|
if transparent.include? color
|
||||||
|
data << 0
|
||||||
|
else
|
||||||
|
data << colors.index(color)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
frame.rows.times do |y|
|
||||||
|
frame.columns.times do |x|
|
||||||
|
color = frame.pixel_color(x, y).to_color(Magick::AllCompliance, true, 8, true)
|
||||||
|
p_color = p_frame.pixel_color(x, y).to_color(Magick::AllCompliance, true, 8, true)
|
||||||
|
|
||||||
|
if color==p_color
|
||||||
|
data << 0
|
||||||
|
elsif transparent.include? color
|
||||||
|
data << 1
|
||||||
|
else
|
||||||
|
data << colors.index(color)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
frames_data << data
|
||||||
|
p_frame = frame
|
||||||
|
end
|
||||||
|
|
||||||
|
data = frames_data.map{|d| compress(d, true)}
|
||||||
|
|
||||||
|
puts "uint8_t #{name}_data[] = {\n #{data.map{|d| d.join(",")}.join(",\n ")}\n};"
|
||||||
|
s=0
|
||||||
|
puts "uint16_t #{name}_offsets[] = {#{(data.map{|d| t=s; s+=d.count; t} + [s]).join(",")}};"
|
||||||
|
|
||||||
|
puts "AnimationData #{name} = {&#{name}_colors[0], &#{name}_data[0], &#{name}_offsets[0], #{colors.count}, #{frames_data.count}, 16, 16};"
|
||||||
|
puts
|
||||||
|
puts
|
||||||
|
puts "Space usage:"
|
||||||
|
puts " Colors: %6d bytes." % [s1=colors.count * 3]
|
||||||
|
puts " Data: %6d bytes." % [s2=data.flatten.count]
|
||||||
|
puts " Offsets: %6d bytes." % [s3=data.count * 2]
|
||||||
|
puts " TOTAL: %6d bytes." % [s1+s2+s3]
|
||||||
|
puts "Original size: %6d bytes." % [s4=File.new(image_file).size]
|
||||||
|
puts "Difference: %6d bytes." % [s1+s2+s3 - s4]
|
Loading…
Reference in New Issue
Block a user