simple_gif 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/simple_gif/size.rb +107 -0
  3. metadata +44 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b9f4059ff0fefe827c694a8eb16268e3c64b20f1
4
+ data.tar.gz: 3706bd0d9fafb8fe1e332090821b25249ddf5b80
5
+ SHA512:
6
+ metadata.gz: 7566aade650d0d6b04d71cdad549fa7b34af5f179702ae2d3a0b8e6dda2f4f7db621acbec0f168edea77bede7ae76a8dd842bbfe540bb746ffd855d9a01979f4
7
+ data.tar.gz: 75f3a78957bbf7112d67c7ffe2e4c068eee5e6dbfdc2b401741925d8277e3ace3ad7b45cf016febe148629865c766436ece78d2f73bc49d65a16865e309ad09b
@@ -0,0 +1,107 @@
1
+ # TODO
2
+ # do not store first frame -- use background color
3
+ # this would help with add[diff:...] for the first frame
4
+
5
+ def writeGIF **_kwargs
6
+ kwargs = {filename: "temp.gif", background: [255,255,255]}.merge _kwargs
7
+ file = File.open kwargs[:filename], "wb:ASCII-8BIT"
8
+
9
+ current = history = width = height = nil
10
+ yield lambda{ |frame|
11
+ width, height = frame.is_a?(Array) ? [frame.first.size, frame.size] : [kwargs[:width], kwargs[:height]]
12
+ history, current = [], Array.new(width * height, kwargs[:background]) unless history
13
+ step = {}
14
+ if frame.is_a? Array
15
+ current = frame.flatten(1).zip(current).map.with_index{ |(color, cur), i|
16
+ step[i] = color if cur != color
17
+ color
18
+ }
19
+ else
20
+ for (i, j), color in frame
21
+ k = i * width + j
22
+ step[k] = current[k] = color if current[k] != color
23
+ end
24
+ end
25
+ history << step unless step.empty?
26
+ # p history.size
27
+ }
28
+ ensure
29
+ file.write "GIF89a"
30
+
31
+ # Logical Screen Descriptor
32
+ file.write [width, height].pack "SS"
33
+ file.write "\xF7\x00\x00"
34
+
35
+ # Global Color Table
36
+ color_table = history.flat_map(&:values).uniq
37
+ raise "sorry, can't have more than 255 colors" if color_table.size > 255
38
+ color_table[255] = [([*0..255].reverse - color_table.map(&:first))[0]] * 3
39
+ color_table.each{ |i| file.write (i || [255,255,255]).pack "CCC" }
40
+
41
+ # Comment Extension block
42
+ file.write "\x21\xFE\x1F"
43
+ file.write "SimpleGIF (c) Nakilon@gmail.com"
44
+ file.write "\x00"
45
+
46
+ # Application Extension block
47
+ file.write "\x21\xFF\x0B"
48
+ file.write "NETSCAPE2.0"
49
+ file.write "\x03\x01\x00\x00\x00"
50
+
51
+ for step in history#.drop 1
52
+
53
+ ### Graphic Control Extension
54
+ file.write "\x21\xF9\x04\x01"
55
+ file.write [100/(kwargs[:fps] || 2)].pack "S"
56
+ file.write "\xFF\x00"
57
+
58
+ left, right = step.map{ |k,| k % width }.minmax
59
+ top, bottom = step.map{ |k,| k / width }.minmax
60
+
61
+ # Image Descriptor
62
+ file.write "\x2C"
63
+ file.write [left, top, right-left+1, bottom-top+1].pack "S*"
64
+ file.write "\x00"
65
+
66
+ # Image Data
67
+ file.write "\x08"
68
+
69
+ indices = Array.new((right-left+1) * (bottom-top+1), 255)
70
+ step.each{ |k,v| indices[
71
+ k - width*top - left - \
72
+ (left + width - right - 1)*(k/width - top)
73
+ ] = color_table.index v }
74
+
75
+ result = []
76
+ table = (0..257).zip
77
+ tree = (0..257).map{[]}
78
+ s = []
79
+ indices.zip do |b| sb = s + b
80
+ next s = sb if sb.inject(tree){ |t,i| t && t[i] }
81
+ result << [table.index(s), (table.size - 1).to_s(2).size]
82
+ table << sb
83
+ sb.inject(tree){ |i,j| i[j] ||= [] }
84
+ s = b
85
+ end
86
+ x = [[256, 9], *result, table.index(s), 257].
87
+ map{ |i, bs| "%0#{bs || result.last.last}b" % i }.
88
+ reverse.join.reverse.
89
+ scan(/.{1,8}/).map{ |i| i.reverse.to_i 2 }
90
+
91
+ begin
92
+ chunk = x[0,255]
93
+ file.write [chunk.size, *chunk].pack "C*"
94
+ end while x = x[255..-1]
95
+
96
+ file.write "\x00"
97
+
98
+ end
99
+
100
+ file.write "\x3B"
101
+ file.close
102
+
103
+ `open -a "/Applications/Google Chrome.app" '#{kwargs[:filename]}'` \
104
+ if kwargs[:open]
105
+ end
106
+
107
+ require_relative(ARGV[0] || "../../examples/life.rb") if $0 == __FILE__
metadata ADDED
@@ -0,0 +1,44 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: simple_gif
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Victor Maslov
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-10-12 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: This is uploaded only for personal usage yet.
14
+ email: nakilon@gmail.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/simple_gif/size.rb
20
+ homepage: http://rubygems.org/gems/simple_gif
21
+ licenses:
22
+ - MIT
23
+ metadata: {}
24
+ post_install_message:
25
+ rdoc_options: []
26
+ require_paths:
27
+ - lib
28
+ required_ruby_version: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - '>='
31
+ - !ruby/object:Gem::Version
32
+ version: 2.0.0
33
+ required_rubygems_version: !ruby/object:Gem::Requirement
34
+ requirements:
35
+ - - '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ requirements: []
39
+ rubyforge_project:
40
+ rubygems_version: 2.0.14
41
+ signing_key:
42
+ specification_version: 4
43
+ summary: A simple GIF renderer.
44
+ test_files: []