flash-header 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +22 -0
- data/README +3 -0
- data/Rakefile +74 -0
- data/bin/flash_header +16 -0
- data/lib/bit_unpacker.rb +74 -0
- data/lib/flash_header.rb +80 -0
- metadata +64 -0
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2007 Manfred Stienstra <m.stienstra@fngtps.com>
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person
|
4
|
+
obtaining a copy of this software and associated documentation
|
5
|
+
files (the "Software"), to deal in the Software without
|
6
|
+
restriction, including without limitation the rights to use,
|
7
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
copies of the Software, and to permit persons to whom the
|
9
|
+
Software is furnished to do so, subject to the following
|
10
|
+
conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
17
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
19
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
20
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
21
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/clean'
|
3
|
+
require 'rake/testtask'
|
4
|
+
require 'rake/gempackagetask'
|
5
|
+
require 'rake/rdoctask'
|
6
|
+
|
7
|
+
NAME = 'flash-header'
|
8
|
+
VERSIE = '0.1'
|
9
|
+
RDOC_OPTS = ['--quiet', '--title', "Flash-header",
|
10
|
+
"--opname", "index.html",
|
11
|
+
"--line-numbers",
|
12
|
+
"--main", "README",
|
13
|
+
"--charset", "utf-8",
|
14
|
+
"--inline-source"]
|
15
|
+
CLEAN.include ['pkg', 'doc', '*.gem']
|
16
|
+
|
17
|
+
desc 'Default: run tests'
|
18
|
+
task :default => [:test]
|
19
|
+
task :package => [:clean]
|
20
|
+
|
21
|
+
desc 'Run tests'
|
22
|
+
Rake::TestTask.new(:test) do |t|
|
23
|
+
t.pattern = 'test/**/*_test.rb'
|
24
|
+
t.verbose = true
|
25
|
+
t.warning = true
|
26
|
+
end
|
27
|
+
|
28
|
+
desc 'Create documentation'
|
29
|
+
Rake::RDocTask.new("doc") do |rdoc|
|
30
|
+
rdoc.rdoc_dir = 'doc'
|
31
|
+
rdoc.options += RDOC_OPTS
|
32
|
+
rdoc.main = "README"
|
33
|
+
rdoc.rdoc_files.include('README')
|
34
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
35
|
+
end
|
36
|
+
|
37
|
+
spec =
|
38
|
+
Gem::Specification.new do |s|
|
39
|
+
s.name = NAME
|
40
|
+
s.version = VERSIE
|
41
|
+
s.platform = Gem::Platform::RUBY
|
42
|
+
s.has_rdoc = true
|
43
|
+
s.extra_rdoc_files = ["README", "LICENSE"]
|
44
|
+
s.rdoc_options += RDOC_OPTS + ['--exclude', '^(examples|test)\/']
|
45
|
+
s.summary = "Library for parsing the headers of a Shockwave Flash file"
|
46
|
+
s.description = "Pure ruby library for parsing the headers of a Shockwave Flash file."
|
47
|
+
s.author = "Manfred Stienstra"
|
48
|
+
s.email = 'manfred@fngtps.com'
|
49
|
+
s.homepage = 'https://fngtps.com/projects/flash-header'
|
50
|
+
s.required_ruby_version = '>= 1.8.0'
|
51
|
+
|
52
|
+
s.files = %w(README LICENSE Rakefile) +
|
53
|
+
Dir.glob("lib/**/*") +
|
54
|
+
Dir.glob("examples/**/*") +
|
55
|
+
Dir.glob("bin/**/*")
|
56
|
+
|
57
|
+
s.require_path = "lib"
|
58
|
+
s.bindir = "bin"
|
59
|
+
s.executables = %w(flash_header)
|
60
|
+
end
|
61
|
+
|
62
|
+
Rake::GemPackageTask.new(spec) do |p|
|
63
|
+
p.need_tar = true
|
64
|
+
p.gem_spec = spec
|
65
|
+
end
|
66
|
+
|
67
|
+
task :install do
|
68
|
+
sh %{rake package}
|
69
|
+
sh %{sudo gem install pkg/#{NAME}-#{VERSIE}}
|
70
|
+
end
|
71
|
+
|
72
|
+
task :uninstall => [:clean] do
|
73
|
+
sh %{sudo gem uninstall #{NAME}}
|
74
|
+
end
|
data/bin/flash_header
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems' rescue LoadError
|
4
|
+
require 'flash_header'
|
5
|
+
|
6
|
+
if ARGV[0]
|
7
|
+
header = FlashHeader.new ARGV[0]
|
8
|
+
else
|
9
|
+
header = FlashHeader.new
|
10
|
+
header.file = $stdin
|
11
|
+
header.read_header
|
12
|
+
end
|
13
|
+
|
14
|
+
%w(signature version size width heigth).each do |attribute|
|
15
|
+
puts "#{attribute.capitalize}: #{header.header[attribute.intern]}"
|
16
|
+
end
|
data/lib/bit_unpacker.rb
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
# The BitUnPacker class unpacks the byte-packed format used in Flash files. In most cases data types
|
2
|
+
# are stored as a number of complete bytes, in file formats where size matters a lot some people choose
|
3
|
+
# to store information as packed bytes. This means that the boundary of a value can lie within a byte.
|
4
|
+
class BitUnpacker
|
5
|
+
# Initialize a new BitUnpacker, note that the BitUnpacker is a parse class with a lot of internal
|
6
|
+
# state variables. You probably only want to use the class methods.
|
7
|
+
#
|
8
|
+
# <tt>bytes</tt>: A string with the bytes to unpack
|
9
|
+
# <tt>size</tt>: The number of bits per entry
|
10
|
+
# <tt>parts</tt>: The number of entries to unpack from the string, default is (bytes.length*8)/size
|
11
|
+
# <tt>skip</tt>: The number of bits to skip from the start of the string, default is 0
|
12
|
+
def initialize(bytes, size, parts=nil, skip=nil)
|
13
|
+
# Input
|
14
|
+
@bytes = bytes
|
15
|
+
@size = size
|
16
|
+
@parts = parts || (bytes.length*8)/size
|
17
|
+
@skip = skip || 0
|
18
|
+
# Reader state
|
19
|
+
@bytes_offset = 0
|
20
|
+
@current = @bytes[0]
|
21
|
+
@have = 8
|
22
|
+
if @skip
|
23
|
+
# TODO: skip more than 8 bytes
|
24
|
+
take @skip
|
25
|
+
@have -= @skip
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Take a number of bits from the current byte and shift them away
|
30
|
+
def take(bits)
|
31
|
+
value = @current >> 8 - bits
|
32
|
+
@current = (@current & (0xff >> bits)) << bits
|
33
|
+
value
|
34
|
+
end
|
35
|
+
|
36
|
+
# Unpack by treating every consecutive block of bits as a signed integer
|
37
|
+
def uunpack
|
38
|
+
unpacked = []
|
39
|
+
value = 0
|
40
|
+
@parts.times do
|
41
|
+
# It's signed, so we need the first byte to determine the sign
|
42
|
+
want = @size - 1
|
43
|
+
is_negative = take(1) == 1 ? true : false
|
44
|
+
@have -= 1
|
45
|
+
while want > 0
|
46
|
+
if want < @have
|
47
|
+
value = (value << want) + take(want)
|
48
|
+
@have -= want
|
49
|
+
want = 0
|
50
|
+
else # want > @have
|
51
|
+
value = (value << @have) + take(@have)
|
52
|
+
want -= @have
|
53
|
+
@have = 8
|
54
|
+
|
55
|
+
@bytes_offset += 1
|
56
|
+
@current = @bytes[@bytes_offset]
|
57
|
+
end
|
58
|
+
end
|
59
|
+
unpacked << (is_negative ? -value : value)
|
60
|
+
value = 0
|
61
|
+
end
|
62
|
+
unpacked
|
63
|
+
end
|
64
|
+
|
65
|
+
# Unpack a byte-packed string and interpret the values as a signed integer
|
66
|
+
#
|
67
|
+
# <tt>bytes</tt>: A string with the bytes to unpack
|
68
|
+
# <tt>size</tt>: The number of bits per entry
|
69
|
+
# <tt>parts</tt>: The number of entries to unpack from the string, default is (bytes.length*8)/size
|
70
|
+
# <tt>skip</tt>: The number of bits to skip from the start of the string, default is 0
|
71
|
+
def self.uunpack(bytes, size, parts=nil, skip=nil)
|
72
|
+
BitUnpacker.new(bytes, size, parts, skip).uunpack
|
73
|
+
end
|
74
|
+
end
|
data/lib/flash_header.rb
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'zlib'
|
2
|
+
require 'bit_unpacker'
|
3
|
+
|
4
|
+
# Read and parses the headers of an SWF file.
|
5
|
+
#
|
6
|
+
# Examples:
|
7
|
+
#
|
8
|
+
# header = FlashHeader.new('dog_on_skateboard.swf')
|
9
|
+
# header.size #=> 5234
|
10
|
+
#
|
11
|
+
# header = FlashHeader.new
|
12
|
+
# # You can feed it any object that supports the read method
|
13
|
+
# header.file = StringIO.new(flash_data)
|
14
|
+
# header.read_header
|
15
|
+
# header.width #=> 640
|
16
|
+
# header.height #=> 480
|
17
|
+
class FlashHeader
|
18
|
+
# An open IO object to read the headers from.
|
19
|
+
attr_accessor :file
|
20
|
+
# Reader for the instance variable that holds all the header values
|
21
|
+
attr_reader :header
|
22
|
+
|
23
|
+
# Initialize a new FlashHeader instance. This reads the file and parses the header.
|
24
|
+
#
|
25
|
+
# <tt>filename</tt>: A filename for a shockwave flash file (optional).
|
26
|
+
def initialize(filename=nil)
|
27
|
+
@header = {}
|
28
|
+
unless filename.nil?
|
29
|
+
@file = File.open filename
|
30
|
+
begin
|
31
|
+
read_header
|
32
|
+
ensure
|
33
|
+
@file.close
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Read the header of the initialized file
|
39
|
+
def read_header
|
40
|
+
temp = @file.read
|
41
|
+
# Signature is three ASCII bytes, CWS or FWS
|
42
|
+
@header[:signature] = temp[0..2]
|
43
|
+
# Version is one byte version number
|
44
|
+
@header[:version] = temp[3]
|
45
|
+
# Size is LE byte order BE bit order
|
46
|
+
@header[:size] = temp[4..7].unpack('C*').reverse.inject(0) do |t,i|
|
47
|
+
(t << 8) + i
|
48
|
+
end
|
49
|
+
# Chop off the header part we just parsed
|
50
|
+
if compressed?
|
51
|
+
temp = Zlib::Inflate.inflate temp[8..-1]
|
52
|
+
else
|
53
|
+
temp = temp[8..-1]
|
54
|
+
end
|
55
|
+
return if temp.empty?
|
56
|
+
|
57
|
+
# First 5 bits are the number of bits for the RECT structure
|
58
|
+
nbits = temp[0] >> 3
|
59
|
+
# 5 bits + 4 times nbits, byte aligned
|
60
|
+
nbytes = ((5 + nbits*4) / 8.0).ceil
|
61
|
+
bytes = BitUnpacker.uunpack(temp[0..nbytes], nbits, 4, 5)
|
62
|
+
@header[:width] = bytes[1] / 20
|
63
|
+
@header[:heigth] = bytes[3] / 20
|
64
|
+
# TODO: support for framerate and the other thing
|
65
|
+
end
|
66
|
+
|
67
|
+
# Returns true if the file was compressed, otherwise it returns false
|
68
|
+
def compressed?
|
69
|
+
@header[:signature][0..0] == 'C'
|
70
|
+
end
|
71
|
+
|
72
|
+
# Adds method access to the headers; signature, version, size, width and height.
|
73
|
+
def method_missing(m, *a)
|
74
|
+
if @header.has_key?(m.to_sym)
|
75
|
+
@header[m.to_sym]
|
76
|
+
else
|
77
|
+
super
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
metadata
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.4
|
3
|
+
specification_version: 1
|
4
|
+
name: flash-header
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: "0.1"
|
7
|
+
date: 2007-10-07 00:00:00 +02:00
|
8
|
+
summary: Library for parsing the headers of a Shockwave Flash file
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: manfred@fngtps.com
|
12
|
+
homepage: https://fngtps.com/projects/flash-header
|
13
|
+
rubyforge_project:
|
14
|
+
description: Pure ruby library for parsing the headers of a Shockwave Flash file.
|
15
|
+
autorequire:
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.8.0
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
post_install_message:
|
29
|
+
authors:
|
30
|
+
- Manfred Stienstra
|
31
|
+
files:
|
32
|
+
- README
|
33
|
+
- LICENSE
|
34
|
+
- Rakefile
|
35
|
+
- lib/bit_unpacker.rb
|
36
|
+
- lib/flash_header.rb
|
37
|
+
- bin/flash_header
|
38
|
+
test_files: []
|
39
|
+
|
40
|
+
rdoc_options:
|
41
|
+
- --quiet
|
42
|
+
- --title
|
43
|
+
- Flash-header
|
44
|
+
- --opname
|
45
|
+
- index.html
|
46
|
+
- --line-numbers
|
47
|
+
- --main
|
48
|
+
- README
|
49
|
+
- --charset
|
50
|
+
- utf-8
|
51
|
+
- --inline-source
|
52
|
+
- --exclude
|
53
|
+
- ^(examples|test)\/
|
54
|
+
extra_rdoc_files:
|
55
|
+
- README
|
56
|
+
- LICENSE
|
57
|
+
executables:
|
58
|
+
- flash_header
|
59
|
+
extensions: []
|
60
|
+
|
61
|
+
requirements: []
|
62
|
+
|
63
|
+
dependencies: []
|
64
|
+
|