diff --git a/tools/gif2c.rb b/tools/gif2c.rb old mode 100644 new mode 100755 index 71e166a..1a20382 --- a/tools/gif2c.rb +++ b/tools/gif2c.rb @@ -18,7 +18,9 @@ def compress(data, use_cutoff=true) data.each do |x| if x == last count += 1 - else + end + + if x!=last || count==255 if use_cutoff if count <= cutoff count.times { result << last } @@ -57,9 +59,18 @@ image_file=ARGV[0] name=ARGV[1] frames = Magick::ImageList.new(image_file) -puts "Found #{frames.count} frames." +STDERR.puts "Found #{frames.count} frames." -print "Getting colors..." +STDERR.puts "Getting delays..." +ticks_per_second = frames.ticks_per_second +times = [] ; frames.each{|f| times << (1000.0 / ticks_per_second * f.delay).round} +individual_frame_times = true +if times.uniq.count==1 + individual_frame_times = false + times = times[0, 1] +end + +STDERR.print "Getting colors..." colors = [] frames.each do |frame| frame.columns.times do |x| @@ -71,22 +82,25 @@ frames.each do |frame| end colors = colors.uniq -puts " Found #{colors.count} colors." +STDERR.puts " Found #{colors.count} colors." transparent = colors.select{|c| c.end_with? "00"} -puts "#{transparent.count} color(s) being transparent." +STDERR.puts "#{transparent.count} color(s) being transparent." -colors = (["#00000012", "#000000FF"] + (colors - transparent)).uniq -puts "Using #{colors.count} colors." +# color[0] is "keep the color from the previous frame" +# color[1] is "background color" +colors = (["#00000012", "#00000013"] + (colors - transparent)).uniq +STDERR.puts "Using #{colors.count} colors." raise "Number of colors has to be 255 or less!" if colors.count>255 -puts +STDERR.puts puts puts "uint32_t #{name}_colors[] = {#{colors.map{|c| "0x" + c[1, 6]}.join(", ")}};" p_frame = nil frames_data = [] +times = [] frames.each_with_index do |frame, index| data = [] if index==0 # first frame @@ -94,7 +108,7 @@ frames.each_with_index do |frame, index| frame.columns.times do |x| color = frame.pixel_color(x, y).to_color(Magick::AllCompliance, true, 8, true) if transparent.include? color - data << 0 + data << 1 else data << colors.index(color) end @@ -116,23 +130,32 @@ frames.each_with_index do |frame, index| end end end - frames_data << data + time = (1000.0 / ticks_per_second * frame.delay).round + if frame==0 || data.uniq!=[0] + times << time + frames_data << data + else + old_time = times.pop + times << old_time + time + end 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};" +puts "uint16_t #{name}_delays[] = {#{times.join(",")}};" 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 "AnimationData #{name} = {&#{name}_colors[0], &#{name}_data[0], &#{name}_offsets[0], &#{name}_delays[0], #{individual_frame_times}, #{colors.count}, #{frames_data.count}, #{frames.first.columns}, #{frames.first.rows}};" 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] +STDERR.puts +STDERR.puts "Space usage:" +STDERR.puts " Colors: %6d bytes." % [s1=colors.count * 4] # colors are 3-bytes, but we have to use uint32_t, which takes up 4 bytes. +STDERR.puts " Data: %6d bytes." % [s2=data.flatten.count] +STDERR.puts " Delays: %6d bytes." % [s5=times.count * 3 + 1] +STDERR.puts " Offsets: %6d bytes." % [s3=data.count * 2] +STDERR.puts " TOTAL: %6d bytes." % [s1+s2+s3+s5] +STDERR.puts "Original size: %6d bytes." % [s4=File.new(image_file).size] +STDERR.puts "Difference: %6d bytes." % [s1+s2+s3+s5 - s4]