swf_ruby 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -1
- data/README.md +13 -1
- data/bin/swf_as_var_replace +21 -0
- data/bin/swf_dump +12 -2
- data/bin/swf_sprite_replace +19 -0
- data/lib/swf_ruby/replace_target.rb +149 -3
- data/lib/swf_ruby/swf/cxformwithalpha.rb +47 -0
- data/lib/swf_ruby/swf/fillstyle.rb +51 -0
- data/lib/swf_ruby/swf/focalgradient.rb +35 -0
- data/lib/swf_ruby/swf/gradient.rb +31 -0
- data/lib/swf_ruby/swf/gradrecord.rb +26 -0
- data/lib/swf_ruby/swf/header.rb +20 -11
- data/lib/swf_ruby/swf/matrix.rb +50 -0
- data/lib/swf_ruby/swf/rgb.rb +22 -0
- data/lib/swf_ruby/swf/rgba.rb +22 -0
- data/lib/swf_ruby/swf/shapewithstyle.rb +30 -0
- data/lib/swf_ruby/swf/swf_string.rb +21 -0
- data/lib/swf_ruby/swf/tag.rb +126 -0
- data/lib/swf_ruby/swf_dumper.rb +3 -1
- data/lib/swf_ruby/swf_tamperer.rb +37 -11
- data/lib/swf_ruby/version.rb +1 -1
- data/swf_ruby.gemspec +1 -1
- metadata +18 -4
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -9,7 +9,7 @@ SwfRuby is a utilities to dump or manipulate a SWF with Ruby.
|
|
9
9
|
* Used from 'swf_dump' command.
|
10
10
|
* SwfRuby::SwfTamperer
|
11
11
|
* Manipulating(replagcing) resources in SWF.
|
12
|
-
* Used from 'swf_jpeg_replace' and '
|
12
|
+
* Used from 'swf_jpeg_replace', 'swf_lossless_replace', 'swf_as_var_replace' and 'swf_sprite_replace' command.
|
13
13
|
* compatible on ruby-1.8.7 and ruby-1.9.2.
|
14
14
|
|
15
15
|
Dependencies
|
@@ -57,6 +57,18 @@ Replacing GIF/PNG in SWF
|
|
57
57
|
$ swf_lossless_replace samples/sample.swf 120 samples/icon.gif > samples/sample3.swf
|
58
58
|
# <120> is offset to DefineBitsLossless2 resource getting by 'swf_dump'.
|
59
59
|
|
60
|
+
Replacing ActionScript Variable in SWF
|
61
|
+
--------------------------------------
|
62
|
+
|
63
|
+
$ swf_as_var_replace foo.swf bar piyo > foo2.swf
|
64
|
+
# <bar> is variable name. <piyo> is new value to the variable.
|
65
|
+
|
66
|
+
Replacing Sprite(internal movieclip) in SWF
|
67
|
+
-------------------------------------------
|
68
|
+
|
69
|
+
$ swf_sprite_replace foo.swf bar piyo.swf > foo2.swf
|
70
|
+
# <bar> is instance variable name of movieclip. <piyo.swf> is new movieclip file to replace.
|
71
|
+
|
60
72
|
Thanks
|
61
73
|
======
|
62
74
|
|
@@ -0,0 +1,21 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# vim: set fileencoding=utf-8 filetype=ruby ts=2 :
|
3
|
+
# SWF中のAS変数の値(foo = var; な箇所に限る)を差し替える.
|
4
|
+
require 'swf_ruby'
|
5
|
+
|
6
|
+
if ARGV.size != 3
|
7
|
+
print "Specify target swf path, AS var name, and new value for arguments.\n"
|
8
|
+
exit
|
9
|
+
end
|
10
|
+
|
11
|
+
swf_dumper = SwfRuby::SwfDumper.new
|
12
|
+
swf_dumper.open(ARGV[0])
|
13
|
+
|
14
|
+
repl_targets = SwfRuby::AsVarReplaceTarget.build_by_var_name(swf_dumper, ARGV[1]).collect do |t|
|
15
|
+
t.str = ARGV[2].dup
|
16
|
+
t
|
17
|
+
end
|
18
|
+
|
19
|
+
st = SwfRuby::SwfTamperer.new
|
20
|
+
|
21
|
+
print st.replace(swf_dumper.swf.dup, repl_targets)
|
data/bin/swf_dump
CHANGED
@@ -12,14 +12,24 @@ end
|
|
12
12
|
swf = SwfRuby::SwfDumper.new
|
13
13
|
swf.open(ARGV[0])
|
14
14
|
swf.tags.each_with_index do |tag, i|
|
15
|
-
|
15
|
+
character_id = tag.character_id ? "character_id: #{tag.character_id}, " : ""
|
16
|
+
refer_character_id = tag.refer_character_id ? "refer_character_id: #{tag.refer_character_id}, " : ""
|
17
|
+
refer_character_inst_name = tag.refer_character_inst_name ? "refer_character_inst_name: #{tag.refer_character_inst_name}, " : ""
|
18
|
+
refer_bitmap_id = ""
|
19
|
+
tag.refer_bitmap_offsets_to_ids.each do |offset, bitmap_id|
|
20
|
+
refer_bitmap_id += "bitmap_id: #{bitmap_id}(offset: #{offset}), "
|
21
|
+
end if tag.refer_bitmap_offsets_to_ids
|
22
|
+
print "#{SwfRuby::Swf::TAG_TYPE[tag.code]}, offset: #{swf.tags_addresses[i]}, #{character_id}#{refer_character_id}#{refer_character_inst_name}#{refer_bitmap_id}length: #{tag.length}\n"
|
16
23
|
if tag.code == 39
|
17
24
|
# DefineSprite
|
18
25
|
sd = SwfRuby::SpriteDumper.new
|
19
26
|
sd.dump(tag)
|
20
27
|
print " Sprite ID: #{sd.sprite_id}, Frame Count: #{sd.frame_count}\n"
|
21
28
|
sd.tags.each_with_index do |tag2, k|
|
22
|
-
|
29
|
+
character_id = tag2.character_id ? "character_id: #{tag2.character_id}, " : ""
|
30
|
+
refer_character_id = tag2.refer_character_id ? "refer_character_id: #{tag2.refer_character_id}, " : ""
|
31
|
+
refer_character_inst_name = tag2.refer_character_inst_name ? "refer_character_inst_name: #{tag2.refer_character_inst_name}, " : ""
|
32
|
+
print " #{SwfRuby::Swf::TAG_TYPE[tag2.code]}, offset: #{sd.tags_addresses[k]}, #{character_id}#{refer_character_id}#{refer_character_inst_name}length: #{tag2.length}\n"
|
23
33
|
if tag2.code == 12
|
24
34
|
# DoAction
|
25
35
|
dad = SwfRuby::DoActionDumper.new
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# vim: set fileencoding=utf-8 filetype=ruby ts=2 :
|
3
|
+
# SWF中の指定したインスタンス変数名で設置されているDefineSpriteを入れ替える.
|
4
|
+
require 'swf_ruby'
|
5
|
+
|
6
|
+
if ARGV.size != 3
|
7
|
+
print "Specify target swf path, sprite instance variable name, and swf path to embed for arguments.\n"
|
8
|
+
exit
|
9
|
+
end
|
10
|
+
|
11
|
+
swf_dumper = SwfRuby::SwfDumper.new
|
12
|
+
swf_dumper.open(ARGV[0])
|
13
|
+
sprite_swf = File.open(ARGV[2], "rb").read
|
14
|
+
|
15
|
+
repl_targets = SwfRuby::SpriteReplaceTarget.build_list_by_instance_var_names(swf_dumper, { ARGV[1] => sprite_swf })
|
16
|
+
|
17
|
+
st = SwfRuby::SwfTamperer.new
|
18
|
+
|
19
|
+
print st.replace(swf_dumper.swf.dup, repl_targets)
|
@@ -23,16 +23,162 @@ module SwfRuby
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
+
class SpriteReplaceTarget < ReplaceTarget
|
27
|
+
attr_accessor :swf
|
28
|
+
attr_accessor :frame_count
|
29
|
+
attr_accessor :define_tags
|
30
|
+
attr_accessor :control_tags
|
31
|
+
attr_accessor :idmap
|
32
|
+
attr_accessor :target_define_tags_string
|
33
|
+
attr_accessor :target_control_tags_string
|
34
|
+
|
35
|
+
def initialize(offset, swf)
|
36
|
+
@offset = offset
|
37
|
+
@swf = swf
|
38
|
+
@target_swf_dumper = SwfDumper.new.dump(@swf)
|
39
|
+
@frame_count = @target_swf_dumper.header.frame_count
|
40
|
+
@define_tags = @target_swf_dumper.tags.select { |t| t.define_tag? }
|
41
|
+
@control_tags = @target_swf_dumper.tags - @define_tags
|
42
|
+
@idmap = {}
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.build_list_by_instance_var_names(swf_dumper, var_name_to_swf)
|
46
|
+
from_character_id = (swf_dumper.tags.collect { |t| t.define_tag? ? t.character_id : nil }).compact.max + 1
|
47
|
+
repl_targets = []
|
48
|
+
var_name_to_swf.each do |var_name, swf|
|
49
|
+
repl_target, from_character_id = SwfRuby::SpriteReplaceTarget.build_by_instance_var_name(swf_dumper, var_name, swf, from_character_id)
|
50
|
+
repl_targets << repl_target
|
51
|
+
end
|
52
|
+
repl_targets
|
53
|
+
end
|
54
|
+
|
55
|
+
# 指定したインスタンス変数名に対するSpriteReplaceTargetを生成する
|
56
|
+
def self.build_by_instance_var_name(swf_dumper, var_name, swf, from_character_id = nil)
|
57
|
+
from_character_id ||= (swf_dumper.tags.collect { |t| t.define_tag? ? t.character_id : nil }).compact.max + 1
|
58
|
+
refer_character_id = nil
|
59
|
+
sprite_indices = {}
|
60
|
+
swf_dumper.tags.each_with_index do |t,i|
|
61
|
+
if t.character_id
|
62
|
+
sprite_indices[t.character_id] = i
|
63
|
+
end
|
64
|
+
if var_name == t.refer_character_inst_name
|
65
|
+
refer_character_id = t.refer_character_id
|
66
|
+
break
|
67
|
+
end
|
68
|
+
end
|
69
|
+
raise ReplaceTargetError unless refer_character_id
|
70
|
+
offset = swf_dumper.tags_addresses[sprite_indices[refer_character_id]]
|
71
|
+
srt = SpriteReplaceTarget.new(offset, swf)
|
72
|
+
srt.target_define_tags_string, from_character_id = srt.build_define_tags_string(from_character_id)
|
73
|
+
srt.target_control_tags_string = srt.build_control_tags_string
|
74
|
+
[srt, from_character_id]
|
75
|
+
end
|
76
|
+
|
77
|
+
# 置換するSWFからCharacterIdを付け替えながらDefineタグを抽出する.
|
78
|
+
# 対象のSWFにBitmapIDの参照が含まれる場合、これも合わせて付け替える.
|
79
|
+
# 同時に、CharacterIdの対応付けマップを作成する.
|
80
|
+
def build_define_tags_string(from_character_id)
|
81
|
+
str = ""
|
82
|
+
@define_tags.each do |t|
|
83
|
+
if t.character_id
|
84
|
+
from_character_id += 1
|
85
|
+
@idmap[t.character_id] = from_character_id
|
86
|
+
str << t.rawdata_with_define_character_id(@idmap, @idmap[t.character_id])
|
87
|
+
end
|
88
|
+
end
|
89
|
+
[str, from_character_id+1]
|
90
|
+
end
|
91
|
+
|
92
|
+
# DefineSpriteに埋め込むためのControl tagsのみを抽出する.
|
93
|
+
# 参照先のcharacter_idを変更する必要がある場合は付け替える.
|
94
|
+
def build_control_tags_string
|
95
|
+
str = ""
|
96
|
+
valid_control_tag_codes = [0, 1, 4, 5, 12, 18, 19, 26, 28, 43, 45, 70, 72]
|
97
|
+
@control_tags.each do |t|
|
98
|
+
next unless valid_control_tag_codes.include? t.code
|
99
|
+
if @idmap[t.refer_character_id]
|
100
|
+
str << t.rawdata_with_refer_character_id(@idmap[t.refer_character_id])
|
101
|
+
else
|
102
|
+
str << t.rawdata
|
103
|
+
end
|
104
|
+
end
|
105
|
+
str
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
26
109
|
class AsVarReplaceTarget < ReplaceTarget
|
27
110
|
attr_accessor :do_action_offset
|
28
111
|
attr_accessor :str
|
29
|
-
attr_accessor :
|
112
|
+
attr_accessor :parent_sprite_offset
|
30
113
|
|
31
|
-
def initialize(action_push_offset, do_action_offset, str,
|
114
|
+
def initialize(action_push_offset, do_action_offset, str, parent_sprite_offset = nil)
|
32
115
|
@offset = action_push_offset
|
33
116
|
@do_action_offset = do_action_offset
|
34
117
|
@str = str
|
35
|
-
@
|
118
|
+
@parent_sprite_offset = parent_sprite_offset
|
119
|
+
end
|
120
|
+
|
121
|
+
# 指定したAS変数名に対するAsVarReplaceTargetのリストを生成する
|
122
|
+
def self.build_by_var_name(swf_dumper, var_name)
|
123
|
+
as_var_replace_targets = []
|
124
|
+
swf_dumper.tags.each_with_index do |t, i|
|
125
|
+
if t.code == 39
|
126
|
+
# DefineSprite
|
127
|
+
sd = SpriteDumper.new
|
128
|
+
sd.dump(t)
|
129
|
+
sd.tags.each_with_index do |u, j|
|
130
|
+
if u.code == 12
|
131
|
+
# DoAction in DefineSprite
|
132
|
+
as_var_replace_targets += AsVarReplaceTarget.generate_as_var_replace_target_by_do_action(var_name, swf_dumper, j, sd, swf_dumper.tags_addresses[i])
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
if t.code == 12
|
137
|
+
# DoAction
|
138
|
+
as_var_replace_targets += AsVarReplaceTarget.generate_as_var_replace_target_by_do_action(var_name, swf_dumper, i)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
as_var_replace_targets
|
142
|
+
end
|
143
|
+
|
144
|
+
# 指定したインデックス(SWFまたはSpriteの先頭からカウント)にあるDoAction以下を走査し、
|
145
|
+
# 指定したAS変数名の代入部分を発見し、AsVarReplaceTargetのリストを生成する.
|
146
|
+
def self.generate_as_var_replace_target_by_do_action(var_name, swf_dumper, do_action_index, sprite_dumper = nil, parent_sprite_offset = nil)
|
147
|
+
as_var_replace_targets = []
|
148
|
+
action_records = []
|
149
|
+
do_action_offset = 0
|
150
|
+
|
151
|
+
dad = DoActionDumper.new
|
152
|
+
if sprite_dumper
|
153
|
+
do_action_offset = parent_sprite_offset + sprite_dumper.tags_addresses[do_action_index]
|
154
|
+
dad.dump(swf_dumper.swf[do_action_offset, sprite_dumper.tags[do_action_index].length])
|
155
|
+
else
|
156
|
+
do_action_offset = swf_dumper.tags_addresses[do_action_index]
|
157
|
+
dad.dump(swf_dumper.swf[do_action_offset, swf_dumper.tags[do_action_index].length])
|
158
|
+
end
|
159
|
+
dad.actions.each_with_index do |ar, i|
|
160
|
+
# ActionPush, ActionPush, SetVariableの並びを検出したら変数名をチェック.
|
161
|
+
action_records.shift if action_records.length > 2
|
162
|
+
action_records << ar
|
163
|
+
if ar.code == 29 and
|
164
|
+
action_records[0] and
|
165
|
+
action_records[0].code == 150 and
|
166
|
+
action_records[0].data.delete("\0") == var_name and
|
167
|
+
action_records[1].code == 150
|
168
|
+
# 対象の代入式を発見.
|
169
|
+
ap = Swf::ActionPush.new(action_records[1])
|
170
|
+
as_var_replace_targets << AsVarReplaceTarget.new(
|
171
|
+
do_action_offset + dad.actions_addresses[i] - action_records[1].length,
|
172
|
+
do_action_offset,
|
173
|
+
"",
|
174
|
+
parent_sprite_offset
|
175
|
+
)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
as_var_replace_targets
|
36
179
|
end
|
37
180
|
end
|
181
|
+
|
182
|
+
# 置換対象指定エラー.
|
183
|
+
class ReplaceTargetError < StandardError; end
|
38
184
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# vim: set fileencoding=utf-8 filetype=ruby ts=2 :
|
2
|
+
|
3
|
+
module SwfRuby
|
4
|
+
module Swf
|
5
|
+
class Cxformwithalpha
|
6
|
+
attr_accessor :has_add_terms
|
7
|
+
attr_accessor :has_mult_terms
|
8
|
+
attr_accessor :nbits
|
9
|
+
attr_accessor :red_mult_term
|
10
|
+
attr_accessor :green_mult_term
|
11
|
+
attr_accessor :blue_mult_term
|
12
|
+
attr_accessor :alpha_mult_term
|
13
|
+
attr_accessor :red_add_term
|
14
|
+
attr_accessor :green_add_term
|
15
|
+
attr_accessor :blue_add_term
|
16
|
+
attr_accessor :alpha_add_term
|
17
|
+
attr_reader :length # byte_aligned
|
18
|
+
|
19
|
+
def initialize(bytearray)
|
20
|
+
bits_str = bytearray.unpack("B*").first
|
21
|
+
@has_add_terms = bits_str[0, 1].to_i(2)
|
22
|
+
@has_mult_terms = bits_str[1, 1].to_i(2)
|
23
|
+
@nbits = bits_str[2, 4].to_i(2)
|
24
|
+
offset = 6
|
25
|
+
if @has_mult_terms == 1
|
26
|
+
# TODO to get as signed bit values!!
|
27
|
+
@red_mult_term = bits_str[offset, @nbits].to_i(2)
|
28
|
+
@green_mult_term = bits_str[offset+@nbits, @nbits].to_i(2)
|
29
|
+
@blue_mult_term = bits_str[offset+2*@nbits, @nbits].to_i(2)
|
30
|
+
@alpha_mult_term = bits_str[offset+3*@nbits, @nbits].to_i(2)
|
31
|
+
offset += 4 * @nbits
|
32
|
+
end
|
33
|
+
if @has_add_terms == 1
|
34
|
+
# TODO to get as signed bit values!!
|
35
|
+
@red_add_term = bits_str[offset, @nbits].to_i(2)
|
36
|
+
@green_add_term = bits_str[offset+@nbits, @nbits].to_i(2)
|
37
|
+
@blue_add_term = bits_str[offset+2*@nbits, @nbits].to_i(2)
|
38
|
+
@alpha_add_term = bits_str[offset+3*@nbits, @nbits].to_i(2)
|
39
|
+
offset += 4 * @nbits
|
40
|
+
end
|
41
|
+
@length = offset >> 3
|
42
|
+
@length += 1 if offset & 7 > 0
|
43
|
+
self
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# vim: set fileencoding=utf-8 filetype=ruby ts=2 :
|
2
|
+
|
3
|
+
module SwfRuby
|
4
|
+
module Swf
|
5
|
+
class Fillstyle
|
6
|
+
attr_accessor :shape_version
|
7
|
+
attr_accessor :fill_style_type
|
8
|
+
attr_accessor :color
|
9
|
+
attr_accessor :gradient_matrix
|
10
|
+
attr_accessor :gradient
|
11
|
+
attr_accessor :bitmap_id
|
12
|
+
attr_accessor :bitmap_id_offset
|
13
|
+
attr_accessor :bitmap_matrix
|
14
|
+
attr_reader :length
|
15
|
+
|
16
|
+
def initialize(bytearray, shape_version)
|
17
|
+
@shape_version = shape_version
|
18
|
+
@fill_style_type = bytearray[0, 1].unpack("C").first
|
19
|
+
offset = 1
|
20
|
+
if @fill_style_type == 0x00
|
21
|
+
if @shape_version >= 3
|
22
|
+
@color = SwfRuby::Swf::Rgba.new(bytearray[offset..-1])
|
23
|
+
else
|
24
|
+
@color = SwfRuby::Swf::Rgb.new(bytearray[offset..-1])
|
25
|
+
end
|
26
|
+
offset += @color.length
|
27
|
+
end
|
28
|
+
if @fill_style_type == 0x10 or @fill_style_type == 0x12 or @fill_style_type == 0x13
|
29
|
+
@gradient_matrix = SwfRuby::Swf::Matrix.new(bytearray[offset..-1])
|
30
|
+
offset += @gradient_matrix.length
|
31
|
+
end
|
32
|
+
if @fill_style_type == 0x10 or @fill_style_type == 0x12
|
33
|
+
@gradient = SwfRuby::Swf::Gradient.new(bytearray[offset..-1], @shape_version)
|
34
|
+
offset += @gradient.length
|
35
|
+
elsif @fill_style_type == 0x13
|
36
|
+
@gradient = SwfRuby::Swf::Focalgradient.new(bytearray[offset..-1], @shape_version)
|
37
|
+
offset += @gradient.length
|
38
|
+
end
|
39
|
+
if @fill_style_type == 0x40 or @fill_style_type == 0x41 or @fill_style_type == 0x42 or @fill_style_type == 0x43
|
40
|
+
@bitmap_id = bytearray[offset, 2].unpack("v").first
|
41
|
+
@bitmap_id_offset = offset
|
42
|
+
offset += 2
|
43
|
+
@bitmap_matrix = SwfRuby::Swf::Matrix.new(bytearray[offset..-1])
|
44
|
+
offset += @bitmap_matrix.length
|
45
|
+
end
|
46
|
+
@length = offset
|
47
|
+
self
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# vim: set fileencoding=utf-8 filetype=ruby ts=2 :
|
2
|
+
|
3
|
+
module SwfRuby
|
4
|
+
module Swf
|
5
|
+
class Focalgradient
|
6
|
+
attr_accessor :shape_version
|
7
|
+
attr_accessor :spread_mode
|
8
|
+
attr_accessor :interpolation_mode
|
9
|
+
attr_accessor :num_gradients
|
10
|
+
attr_accessor :gradient_records
|
11
|
+
attr_accessor :focal_point
|
12
|
+
attr_reader :length
|
13
|
+
|
14
|
+
def initialize(bytearray, shape_version)
|
15
|
+
@shape_version = shape_version
|
16
|
+
bits_str = bytearray[0, 1].unpack("B").first
|
17
|
+
@spread_mode = bits_str[0, 2].to_i(2)
|
18
|
+
@interpolation_mode = bits_str[2, 2].to_i(2)
|
19
|
+
@num_gradients = bits_str[4, 4].to_i(2)
|
20
|
+
offset = 1
|
21
|
+
@gradient_records = []
|
22
|
+
@num_gradients.times do
|
23
|
+
gradient_record = SwfRuby::Swf::Gradrecord.new(bytearray[offset..-1], @shape_version)
|
24
|
+
@gradient_records << gradient_record
|
25
|
+
offset += gradient_record.length
|
26
|
+
end
|
27
|
+
# TODO focal_point to be 8bit.8bit fixed_point number.
|
28
|
+
@focal_point = bytearray[offset, 2]
|
29
|
+
offset += 2
|
30
|
+
@length = offset
|
31
|
+
self
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# vim: set fileencoding=utf-8 filetype=ruby ts=2 :
|
2
|
+
|
3
|
+
module SwfRuby
|
4
|
+
module Swf
|
5
|
+
class Gradient
|
6
|
+
attr_accessor :shape_version
|
7
|
+
attr_accessor :spread_mode
|
8
|
+
attr_accessor :interpolation_mode
|
9
|
+
attr_accessor :num_gradients
|
10
|
+
attr_accessor :gradient_records
|
11
|
+
attr_reader :length
|
12
|
+
|
13
|
+
def initialize(bytearray, shape_version)
|
14
|
+
@shape_version = shape_version
|
15
|
+
bits_str = bytearray[0, 1].unpack("B").first
|
16
|
+
@spread_mode = bits_str[0, 2].to_i(2)
|
17
|
+
@interpolation_mode = bits_str[2, 2].to_i(2)
|
18
|
+
@num_gradients = bits_str[4, 4].to_i(2)
|
19
|
+
offset = 1
|
20
|
+
@gradient_records = []
|
21
|
+
@num_gradients.times do
|
22
|
+
gradient_record = SwfRuby::Swf::Gradrecord.new(bytearray[offset..-1], @shape_version)
|
23
|
+
@gradient_records << gradient_record
|
24
|
+
offset += gradient_record.length
|
25
|
+
end
|
26
|
+
@length = offset
|
27
|
+
self
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# vim: set fileencoding=utf-8 filetype=ruby ts=2 :
|
2
|
+
|
3
|
+
module SwfRuby
|
4
|
+
module Swf
|
5
|
+
class Gradrecord
|
6
|
+
attr_accessor :shape_version
|
7
|
+
attr_accessor :ratio
|
8
|
+
attr_accessor :color
|
9
|
+
attr_reader :length
|
10
|
+
|
11
|
+
def initialize(bytearray, shape_version)
|
12
|
+
@shape_version = shape_version
|
13
|
+
@ratio = bytearray[0, 1].unpack("C").first
|
14
|
+
offset = 1
|
15
|
+
if @shape_version >= 3
|
16
|
+
@color = SwfRuby::Swf::Rgba.new(bytearray[offset..-1])
|
17
|
+
else
|
18
|
+
@color = SwfRuby::Swf::Rgb.new(bytearray[offset..-1])
|
19
|
+
end
|
20
|
+
offset += @color.length
|
21
|
+
@length = offset
|
22
|
+
self
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/swf_ruby/swf/header.rb
CHANGED
@@ -9,30 +9,39 @@ module SwfRuby
|
|
9
9
|
attr_accessor :frame_size
|
10
10
|
attr_accessor :frame_rate
|
11
11
|
attr_accessor :frame_count
|
12
|
-
|
12
|
+
attr_accessor :length
|
13
13
|
|
14
|
-
def
|
14
|
+
def self.parse(swf)
|
15
|
+
header = Header.new
|
15
16
|
# check if compressed
|
16
17
|
if swf[1].chr == "W" and swf[2].chr == "S"
|
17
18
|
if swf[0].chr == "F"
|
18
|
-
|
19
|
+
header.compressed = false
|
19
20
|
elsif swf[0].chr == "C"
|
20
|
-
|
21
|
+
header.compressed = true
|
21
22
|
end
|
22
23
|
end
|
23
24
|
# version
|
24
|
-
|
25
|
+
header.version = swf[3].chr.unpack("C").first
|
25
26
|
# file size
|
26
|
-
|
27
|
+
header.file_length = swf[4, 4].unpack("V").first
|
28
|
+
|
29
|
+
# Zlib inflate
|
30
|
+
if header.compressed
|
31
|
+
swf[8..-1] = Zlib::Inflate.inflate(swf[8..-1])
|
32
|
+
end
|
33
|
+
|
27
34
|
# frame size
|
28
|
-
|
35
|
+
header.frame_size = Rectangle.new(swf[8..-1])
|
29
36
|
# frame rate
|
30
|
-
|
31
|
-
|
37
|
+
header.frame_rate = (swf[8+header.frame_size.length].chr.unpack("C").first).to_f / 0x100
|
38
|
+
header.frame_rate += swf[9+header.frame_size.length].chr.unpack("C").first
|
32
39
|
# frame count
|
33
|
-
|
40
|
+
header.frame_count = swf[10+header.frame_size.length, 2].unpack("v").first
|
34
41
|
# header length
|
35
|
-
|
42
|
+
header.length = 12+header.frame_size.length
|
43
|
+
|
44
|
+
[header, swf]
|
36
45
|
end
|
37
46
|
end
|
38
47
|
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# vim: set fileencoding=utf-8 filetype=ruby ts=2 :
|
2
|
+
|
3
|
+
module SwfRuby
|
4
|
+
module Swf
|
5
|
+
class Matrix
|
6
|
+
attr_accessor :has_scale
|
7
|
+
attr_accessor :n_scale_bits
|
8
|
+
attr_accessor :scale_x
|
9
|
+
attr_accessor :scale_y
|
10
|
+
attr_accessor :has_rotate
|
11
|
+
attr_accessor :n_rotate_bits
|
12
|
+
attr_accessor :rotate_skew_0
|
13
|
+
attr_accessor :rotate_skew_1
|
14
|
+
attr_accessor :n_translate_bits
|
15
|
+
attr_accessor :translate_x
|
16
|
+
attr_accessor :translate_y
|
17
|
+
attr_reader :length # byte_aligned
|
18
|
+
|
19
|
+
def initialize(bytearray)
|
20
|
+
bits_str = bytearray.unpack("B*").first
|
21
|
+
@has_scale = bits_str[0, 1].to_i(2)
|
22
|
+
offset = 1
|
23
|
+
if @has_scale == 1
|
24
|
+
@n_scale_bits = bits_str[offset, 5].to_i(2)
|
25
|
+
offset += 5
|
26
|
+
@scale_x = bits_str[offset, self.n_scale_bits].to_i(2)
|
27
|
+
@scale_y = bits_str[offset+self.n_scale_bits, self.n_scale_bits].to_i(2)
|
28
|
+
offset += 2 * self.n_scale_bits
|
29
|
+
end
|
30
|
+
@has_rotate = bits_str[offset, 1].to_i(2)
|
31
|
+
offset += 1
|
32
|
+
if @has_rotate == 1
|
33
|
+
@n_rotate_bits = bits_str[offset, 5].to_i(2)
|
34
|
+
offset += 5
|
35
|
+
@rotate_skew_0 = bits_str[offset, self.n_rotate_bits].to_i(2)
|
36
|
+
@rotate_skew_1 = bits_str[offset+self.n_rotate_bits, self.n_rotate_bits].to_i(2)
|
37
|
+
offset += 2 * self.n_rotate_bits
|
38
|
+
end
|
39
|
+
@n_translate_bits = bits_str[offset, 5].to_i(2)
|
40
|
+
offset += 5
|
41
|
+
@translate_x = bits_str[offset, self.n_translate_bits].to_i(2)
|
42
|
+
@translate_y = bits_str[offset+self.n_translate_bits, self.n_translate_bits].to_i(2)
|
43
|
+
offset += 2 * self.n_translate_bits
|
44
|
+
@length = offset >> 3
|
45
|
+
@length += 1 if offset & 7 > 0
|
46
|
+
self
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# vim: set fileencoding=utf-8 filetype=ruby ts=2 :
|
2
|
+
|
3
|
+
module SwfRuby
|
4
|
+
module Swf
|
5
|
+
class Rgb
|
6
|
+
|
7
|
+
attr_accessor :red
|
8
|
+
attr_accessor :green
|
9
|
+
attr_accessor :blue
|
10
|
+
attr_reader :length
|
11
|
+
|
12
|
+
def initialize(bytearray)
|
13
|
+
@red = bytearray[0, 1].unpack("C").first
|
14
|
+
@green = bytearray[1, 1].unpack("C").first
|
15
|
+
@blue = bytearray[2, 1].unpack("C").first
|
16
|
+
@length = 3
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# vim: set fileencoding=utf-8 filetype=ruby ts=2 :
|
2
|
+
|
3
|
+
module SwfRuby
|
4
|
+
module Swf
|
5
|
+
class Rgba
|
6
|
+
attr_accessor :red
|
7
|
+
attr_accessor :green
|
8
|
+
attr_accessor :blue
|
9
|
+
attr_accessor :alpha
|
10
|
+
attr_reader :length
|
11
|
+
|
12
|
+
def initialize(bytearray)
|
13
|
+
@red = bytearray[0, 1].unpack("C").first
|
14
|
+
@green = bytearray[1, 1].unpack("C").first
|
15
|
+
@blue = bytearray[2, 1].unpack("C").first
|
16
|
+
@alpha = bytearray[3, 1].unpack("C").first
|
17
|
+
@length = 4
|
18
|
+
self
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# vim: set fileencoding=utf-8 filetype=ruby ts=2 :
|
2
|
+
|
3
|
+
module SwfRuby
|
4
|
+
module Swf
|
5
|
+
class Shapewithstyle
|
6
|
+
attr_accessor :shape_version
|
7
|
+
attr_accessor :fill_styles_with_offset
|
8
|
+
attr_accessor :after_line_styles
|
9
|
+
|
10
|
+
def initialize(bytearray, shape_version)
|
11
|
+
@shape_version = shape_version
|
12
|
+
fill_style_count = bytearray[0, 1].unpack("C").first
|
13
|
+
offset = 1
|
14
|
+
if fill_style_count == 255
|
15
|
+
fill_style_count = bytearray[1, 2].unpack("v").first
|
16
|
+
offset += 2
|
17
|
+
end
|
18
|
+
@fill_styles_with_offset = {}
|
19
|
+
fill_style_count.times do
|
20
|
+
fill_style = SwfRuby::Swf::Fillstyle.new(bytearray[offset..-1], @shape_version)
|
21
|
+
@fill_styles_with_offset[offset] = fill_style
|
22
|
+
offset += fill_style.length
|
23
|
+
end
|
24
|
+
# TODO after_line_styles are including outside tag data..
|
25
|
+
@after_line_styles = bytearray[offset..-1]
|
26
|
+
self
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# vim: set fileencoding=utf-8 filetype=ruby ts=2 :
|
2
|
+
|
3
|
+
module SwfRuby
|
4
|
+
module Swf
|
5
|
+
class SwfString
|
6
|
+
attr_accessor :string
|
7
|
+
attr_reader :length # including StringEndMark
|
8
|
+
|
9
|
+
def initialize(bytearray)
|
10
|
+
@length = 0
|
11
|
+
bytearray.each_byte do |byte|
|
12
|
+
break if byte == 0
|
13
|
+
@length += 1
|
14
|
+
end
|
15
|
+
@string = bytearray[0, @length]
|
16
|
+
@length += 1 # Endmark
|
17
|
+
self
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/swf_ruby/swf/tag.rb
CHANGED
@@ -3,10 +3,16 @@
|
|
3
3
|
module SwfRuby
|
4
4
|
module Swf
|
5
5
|
class Tag
|
6
|
+
attr_reader :rawdata
|
6
7
|
attr_reader :code
|
7
8
|
attr_reader :length
|
8
9
|
attr_reader :long_header
|
9
10
|
attr_reader :data
|
11
|
+
attr_reader :character_id
|
12
|
+
attr_reader :refer_character_id
|
13
|
+
attr_reader :refer_character_id_offset
|
14
|
+
attr_reader :refer_character_inst_name
|
15
|
+
attr_reader :refer_bitmap_offsets_to_ids
|
10
16
|
|
11
17
|
def initialize(swf)
|
12
18
|
swf.force_encoding("ASCII-8BIT") if swf.respond_to? :force_encoding
|
@@ -26,9 +32,129 @@ module SwfRuby
|
|
26
32
|
@data = swf[2, @length]
|
27
33
|
@length += 2
|
28
34
|
end
|
35
|
+
@character_id = nil
|
36
|
+
if self.define_tag?
|
37
|
+
@character_id = @data[0, 2].unpack("v").first
|
38
|
+
end
|
39
|
+
@refer_character_id = nil
|
40
|
+
@refer_character_id_offset = nil
|
41
|
+
@refer_character_inst_name = nil
|
42
|
+
data_offset = @long_header ? 6 : 2
|
43
|
+
case Swf::TAG_TYPE[@code]
|
44
|
+
when "PlaceObject"
|
45
|
+
@refer_character_id_offset = data_offset
|
46
|
+
@refer_character_id = @data[0, 2].unpack("v").first
|
47
|
+
when "PlaceObject2"
|
48
|
+
flags = @data[0, 1].unpack("C").first
|
49
|
+
offset = 3
|
50
|
+
if flags & 2 == 2
|
51
|
+
@refer_character_id_offset = data_offset + offset
|
52
|
+
@refer_character_id = @data[offset, 2].unpack("v").first
|
53
|
+
offset += 2
|
54
|
+
end
|
55
|
+
if flags & 32 == 32
|
56
|
+
if flags & 4 == 4
|
57
|
+
matrix = SwfRuby::Swf::Matrix.new(@data[offset..-1])
|
58
|
+
offset += matrix.length
|
59
|
+
end
|
60
|
+
if flags & 8 == 8
|
61
|
+
cxtfm = SwfRuby::Swf::Cxformwithalpha.new(@data[offset..-1])
|
62
|
+
offset += cxtfm.length
|
63
|
+
end
|
64
|
+
offset += 2 if flags & 16 == 16
|
65
|
+
@refer_character_inst_name = SwfRuby::Swf::SwfString.new(@data[offset..-1]).string
|
66
|
+
end
|
67
|
+
when "PlaceObject3"
|
68
|
+
flags = @data[0, 2].unpack("n").first
|
69
|
+
offset = 4
|
70
|
+
if flags & 8 == 8
|
71
|
+
class_name = SwfRuby::Swf::SwfString.new(@data[offset..-1])
|
72
|
+
offset += class_name.length
|
73
|
+
end
|
74
|
+
if flags & 512 == 512
|
75
|
+
@refer_character_id_offset = data_offset + offset
|
76
|
+
@refer_character_id = @data[offset, 2].unpack("v").first
|
77
|
+
end
|
78
|
+
if flags & 8192 == 8192
|
79
|
+
if flags & 1024 == 1024
|
80
|
+
matrix = SwfRuby::Swf::Matrix.new(@data[offset..-1])
|
81
|
+
offset += matrix.length
|
82
|
+
end
|
83
|
+
if flags & 2048 == 2048
|
84
|
+
cxtfm = SwfRuby::Swf::Cxformwithalpha.new(@data[offset..-1])
|
85
|
+
offset += cxtfm.length
|
86
|
+
end
|
87
|
+
offset += 2 if flags & 4096 == 4096
|
88
|
+
@refer_character_inst_name = SwfRuby::Swf::SwfString.new(@data[offset..-1]).string
|
89
|
+
end
|
90
|
+
when "RemoveObject"
|
91
|
+
@refer_character_id_offset = data_offset
|
92
|
+
@refer_character_id = @data[0, 2].unpack("v").first
|
93
|
+
when "DefineShape"
|
94
|
+
when "DefineShape2"
|
95
|
+
when "DefineShape3"
|
96
|
+
version = Swf::TAG_TYPE[@code][-1].to_i
|
97
|
+
version = 1 if version == 0
|
98
|
+
@refer_bitmap_offsets_to_ids = {}
|
99
|
+
rect = SwfRuby::Swf::Rectangle.new(@data[2..-1])
|
100
|
+
offset = 2+rect.length
|
101
|
+
shapewithstyle = SwfRuby::Swf::Shapewithstyle.new(@data[offset..-1], version)
|
102
|
+
shapewithstyle.fill_styles_with_offset.each do |fs_offset, fs|
|
103
|
+
if fs.bitmap_id
|
104
|
+
o = offset + fs_offset + fs.bitmap_id_offset
|
105
|
+
o += @long_header ? 6 : 2
|
106
|
+
@refer_bitmap_offsets_to_ids[o] = fs.bitmap_id
|
107
|
+
end
|
108
|
+
end
|
109
|
+
when "DefineShape4"
|
110
|
+
version = 4
|
111
|
+
@refer_bitmap_offsets_to_ids = {}
|
112
|
+
shape_rect = SwfRuby::Swf::Rectangle.new(@data[2..-1])
|
113
|
+
offset = 2+shape_rect.length
|
114
|
+
edge_rect = SwfRuby::Swf::Rectangle.new(@data[offset..-1])
|
115
|
+
offset += edge_rect.length
|
116
|
+
offset += 1
|
117
|
+
shapewithstyle = SwfRuby::Swf::Shapewithstyle.new(@data[offset..-1], version)
|
118
|
+
shapewithstyle.fill_styles_with_offset.each do |fs_offset, fs|
|
119
|
+
if fs.bitmap_id
|
120
|
+
o = offset + fs_offset + fs.bitmap_id_offset
|
121
|
+
o += @long_header ? 6 : 2
|
122
|
+
@refer_bitmap_offsets_to_ids[o] = fs.bitmap_id
|
123
|
+
end
|
124
|
+
end
|
125
|
+
else
|
126
|
+
# do nothing.
|
127
|
+
end
|
128
|
+
@rawdata = swf[0, @length]
|
129
|
+
self
|
130
|
+
end
|
131
|
+
|
132
|
+
# Define系タグの冒頭のcharacter_id参照を指定のIDに書き換える.
|
133
|
+
# 内部にBitmapIDの参照を含む場合、渡されたidmapから読み替える値を参照し、書き換える.
|
134
|
+
def rawdata_with_define_character_id(idmap, character_id)
|
135
|
+
if self.define_tag?
|
136
|
+
offset = @long_header ? 6 : 2
|
137
|
+
@rawdata[offset, 2] = [character_id].pack("v")
|
138
|
+
@refer_bitmap_offsets_to_ids.each do |bitmap_id_offset, bitmap_id|
|
139
|
+
@rawdata[bitmap_id_offset, 2] = [idmap[bitmap_id]].pack("v")
|
140
|
+
end if @refer_bitmap_offsets_to_ids
|
141
|
+
end
|
142
|
+
@rawdata
|
29
143
|
end
|
144
|
+
|
145
|
+
def rawdata_with_refer_character_id(character_id)
|
146
|
+
@rawdata[@refer_character_id_offset, 2] = [character_id].pack("v") if @refer_character_id_offset
|
147
|
+
@rawdata
|
148
|
+
end
|
149
|
+
|
150
|
+
def define_tag?
|
151
|
+
Swf::TAG_TYPE[@code] =~ /^Define/
|
152
|
+
end
|
153
|
+
|
30
154
|
end
|
31
155
|
|
156
|
+
class TagError < StandardError; end
|
157
|
+
|
32
158
|
TAG_TYPE = {
|
33
159
|
0=>"End",
|
34
160
|
1=>"ShowFrame",
|
data/lib/swf_ruby/swf_dumper.rb
CHANGED
@@ -7,6 +7,7 @@ module SwfRuby
|
|
7
7
|
attr_reader :header
|
8
8
|
attr_reader :tags
|
9
9
|
attr_reader :tags_addresses
|
10
|
+
attr_accessor :character_ids
|
10
11
|
|
11
12
|
# 初期化.
|
12
13
|
def initialize
|
@@ -27,7 +28,7 @@ module SwfRuby
|
|
27
28
|
# ダンプして構造をインスタンス変数に格納.
|
28
29
|
def dump(swf)
|
29
30
|
@swf = swf
|
30
|
-
@header = Swf::Header.
|
31
|
+
@header, @swf = Swf::Header.parse(@swf)
|
31
32
|
@tags = []
|
32
33
|
@tags_addresses = []
|
33
34
|
tags_length = 0
|
@@ -40,5 +41,6 @@ module SwfRuby
|
|
40
41
|
end
|
41
42
|
self
|
42
43
|
end
|
44
|
+
|
43
45
|
end
|
44
46
|
end
|
@@ -8,20 +8,48 @@ module SwfRuby
|
|
8
8
|
replace_targets.sort_by { |a| a.offset }.reverse.each do |rt|
|
9
9
|
case rt
|
10
10
|
when Jpeg2ReplaceTarget
|
11
|
-
swf =
|
11
|
+
swf = repl_jpeg2(swf, rt.offset, rt.jpeg)
|
12
12
|
when Lossless2ReplaceTarget
|
13
|
-
swf =
|
13
|
+
swf = repl_lossless2(swf, rt.offset, rt.image)
|
14
14
|
when AsVarReplaceTarget
|
15
|
-
swf =
|
15
|
+
swf = repl_action_push_string(swf, rt.do_action_offset, rt.offset, rt.str, rt.parent_sprite_offset)
|
16
|
+
when SpriteReplaceTarget
|
17
|
+
swf = repl_sprite(swf, rt.offset, rt.target_define_tags_string, rt.frame_count, rt.target_control_tags_string)
|
16
18
|
end
|
17
19
|
end
|
18
20
|
swf
|
19
21
|
end
|
20
22
|
|
21
|
-
|
23
|
+
private
|
22
24
|
|
23
|
-
#
|
24
|
-
|
25
|
+
# 対象オフセット位置にあるDefineSpriteを指定したControlTags文字列で置換.
|
26
|
+
# 新しいSprite含むDefineTagsは、DefineSpriteの直前に挿入する.
|
27
|
+
def repl_sprite(swf, offset, define_tags, frame_count, control_tags)
|
28
|
+
swf.force_encoding("ASCII-8BIT") if swf.respond_to? :force_encoding
|
29
|
+
define_tags.force_encoding("ASCII-8BIT") if define_tags.respond_to? :force_encoding
|
30
|
+
control_tags.force_encoding("ASCII-8BIT") if control_tags.respond_to? :force_encoding
|
31
|
+
record_header = swf[offset, 2].unpack("v").first
|
32
|
+
# tag check
|
33
|
+
raise ReplaceTargetError if (record_header >> 6) & 1023 != 39
|
34
|
+
# error for short header (not implemented yet.)
|
35
|
+
raise ReplaceTargetError if record_header & 63 < 63
|
36
|
+
# rewrite frame count
|
37
|
+
swf[offset+8, 2] = [frame_count].pack("v")
|
38
|
+
# rewrite control tag and length
|
39
|
+
sprite_len = swf[offset+2, 4].unpack("i").first # without recordheader
|
40
|
+
old_control_tags_len = sprite_len - 4
|
41
|
+
delta_control_tags_len = control_tags.length - old_control_tags_len
|
42
|
+
swf[offset+10, old_control_tags_len] = control_tags
|
43
|
+
swf[offset+2, 4] = [sprite_len + delta_control_tags_len].pack("V")
|
44
|
+
# insert define tags before define sprite
|
45
|
+
swf[offset, 0] = define_tags
|
46
|
+
# rewrite swf header
|
47
|
+
swf[4, 4] = [swf[4, 4].unpack("V").first + define_tags.length + delta_control_tags_len].pack("V")
|
48
|
+
swf
|
49
|
+
end
|
50
|
+
|
51
|
+
# 対象オフセット位置にあるActionPushデータを置換.
|
52
|
+
def repl_action_push_string(swf, do_action_offset, action_push_offset, str, parent_sprite_offset = nil)
|
25
53
|
swf.force_encoding("ASCII-8BIT") if swf.respond_to? :force_encoding
|
26
54
|
str.force_encoding("ASCII-8BIT") if str.respond_to? :force_encoding
|
27
55
|
record_header = swf[do_action_offset, 2].unpack("v").first
|
@@ -30,10 +58,10 @@ module SwfRuby
|
|
30
58
|
# action check
|
31
59
|
raise ReplaceTargetError if swf[action_push_offset].chr.unpack("C").first != 0x96
|
32
60
|
raise ReplaceTargetError if swf[action_push_offset + 3].chr.unpack("C").first != 0
|
33
|
-
# error
|
61
|
+
# error for short header (not implemented yet.)
|
34
62
|
raise ReplaceTargetError if record_header & 63 < 63
|
35
63
|
# calc length
|
36
|
-
do_action_len = swf[do_action_offset+2, 4].unpack("i").first
|
64
|
+
do_action_len = swf[do_action_offset+2, 4].unpack("i").first # without recordheader
|
37
65
|
action_push_len = swf[action_push_offset+1, 2].unpack("v").first
|
38
66
|
org_str_length = action_push_len - 2 # data type & terminated null
|
39
67
|
delta_str_length = str.length - org_str_length
|
@@ -41,7 +69,7 @@ module SwfRuby
|
|
41
69
|
swf[action_push_offset+4, org_str_length] = str
|
42
70
|
swf[action_push_offset+1, 2] = [action_push_len + delta_str_length].pack("v")
|
43
71
|
swf[do_action_offset+2, 4] = [do_action_len + delta_str_length].pack("V")
|
44
|
-
|
72
|
+
if parent_sprite_offset
|
45
73
|
swf[parent_sprite_offset+2, 4] = [swf[parent_sprite_offset+2, 4].unpack("V").first + delta_str_length].pack("V")
|
46
74
|
end
|
47
75
|
swf[4, 4] = [swf[4, 4].unpack("V").first + delta_str_length].pack("V")
|
@@ -143,6 +171,4 @@ module SwfRuby
|
|
143
171
|
end
|
144
172
|
end
|
145
173
|
|
146
|
-
# 置換対象指定エラー.
|
147
|
-
class ReplaceTargetError < StandardError; end
|
148
174
|
end
|
data/lib/swf_ruby/version.rb
CHANGED
data/swf_ruby.gemspec
CHANGED
@@ -19,7 +19,7 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.add_dependency "rmagick", ">= 2.13.0"
|
20
20
|
|
21
21
|
s.bindir = 'bin'
|
22
|
-
s.executables = ['swf_dump', 'swf_jpeg_replace', 'swf_lossless_replace']
|
22
|
+
s.executables = ['swf_dump', 'swf_jpeg_replace', 'swf_lossless_replace', 'swf_as_var_replace', 'swf_sprite_replace']
|
23
23
|
|
24
24
|
s.files = `git ls-files`.split("\n")
|
25
25
|
s.require_path = 'lib'
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 0.
|
7
|
+
- 2
|
8
|
+
- 0
|
9
|
+
version: 0.2.0
|
10
10
|
platform: ruby
|
11
11
|
authors: []
|
12
12
|
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2011-
|
17
|
+
date: 2011-04-27 00:00:00 +09:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -56,6 +56,8 @@ executables:
|
|
56
56
|
- swf_dump
|
57
57
|
- swf_jpeg_replace
|
58
58
|
- swf_lossless_replace
|
59
|
+
- swf_as_var_replace
|
60
|
+
- swf_sprite_replace
|
59
61
|
extensions: []
|
60
62
|
|
61
63
|
extra_rdoc_files: []
|
@@ -68,9 +70,11 @@ files:
|
|
68
70
|
- Gemfile.lock
|
69
71
|
- README.md
|
70
72
|
- Rakefile
|
73
|
+
- bin/swf_as_var_replace
|
71
74
|
- bin/swf_dump
|
72
75
|
- bin/swf_jpeg_replace
|
73
76
|
- bin/swf_lossless_replace
|
77
|
+
- bin/swf_sprite_replace
|
74
78
|
- lib/swf_ruby.rb
|
75
79
|
- lib/swf_ruby/do_action_dumper.rb
|
76
80
|
- lib/swf_ruby/replace_target.rb
|
@@ -79,8 +83,18 @@ files:
|
|
79
83
|
- lib/swf_ruby/swf/action_push.rb
|
80
84
|
- lib/swf_ruby/swf/action_record.rb
|
81
85
|
- lib/swf_ruby/swf/bits_lossless2.rb
|
86
|
+
- lib/swf_ruby/swf/cxformwithalpha.rb
|
87
|
+
- lib/swf_ruby/swf/fillstyle.rb
|
88
|
+
- lib/swf_ruby/swf/focalgradient.rb
|
89
|
+
- lib/swf_ruby/swf/gradient.rb
|
90
|
+
- lib/swf_ruby/swf/gradrecord.rb
|
82
91
|
- lib/swf_ruby/swf/header.rb
|
92
|
+
- lib/swf_ruby/swf/matrix.rb
|
83
93
|
- lib/swf_ruby/swf/rectangle.rb
|
94
|
+
- lib/swf_ruby/swf/rgb.rb
|
95
|
+
- lib/swf_ruby/swf/rgba.rb
|
96
|
+
- lib/swf_ruby/swf/shapewithstyle.rb
|
97
|
+
- lib/swf_ruby/swf/swf_string.rb
|
84
98
|
- lib/swf_ruby/swf/tag.rb
|
85
99
|
- lib/swf_ruby/swf_dumper.rb
|
86
100
|
- lib/swf_ruby/swf_tamperer.rb
|