flash-header 0.1
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/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
|
+
|