swf_ruby 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|