swf_file 0.1.0 → 1.0.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.
@@ -1,4 +1,4 @@
1
- ==Introduction
1
+ =swf_file
2
2
  Based on the swfutil lib, by Dennis Zhuang, the SWF File is lightweight gem to read swf file headers from within a Ruby application.
3
3
 
4
4
  ==Ruby compatibility
@@ -14,7 +14,23 @@
14
14
  Please refer to the LICENSE file.
15
15
 
16
16
  ==Example
17
- TODO
17
+ swf = SwfFile.header 'clicktag.swf' # load the file
18
+
19
+ # Access the various header options. Please check the unit tests for more usage examples.
20
+ puts swf.size
21
+ puts swf.compressed?
22
+ puts swf.version
23
+ puts swf.bit_count
24
+ puts swf.xmax
25
+ puts swf.ymax
26
+ puts swf.width # In pixels
27
+ puts swf.height # In pixels
28
+ puts swf.frame_rate
29
+ puts swf.frame_count
30
+ puts swf.duration # In milliseconds
31
+ puts swf.avm_version
32
+ puts swf.signature
33
+
18
34
 
19
35
  ==Issues, improvements, feedback an suggestions
20
36
  To report issues, please use GitHub's issue manager (http://github.com/DBA/swf_file/issues). Meanwhile, feel free to fork the project and submit your modifications.
@@ -23,5 +39,5 @@
23
39
 
24
40
  ==Pending
25
41
  * Cleanup the class PackedBitObject, which still suffers from the pure import from SwfUtil
26
- * Modularize SwfHeader a bit more
27
- * Docs
42
+ * Docs
43
+ * Modularize SwfHeader a bit more
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 1.0.0
@@ -0,0 +1,10 @@
1
+ module Assertions
2
+ def compressed?(memoize_result = true)
3
+ buffer_compressed?(memoize_result)
4
+ end
5
+
6
+ private
7
+ def swf?
8
+ @buffer[0,3] == 'FWS' || @buffer[0,3] == 'CWS'
9
+ end
10
+ end
@@ -4,7 +4,7 @@ module Compression
4
4
  if memoize_result
5
5
  @compressed ||= @buffer[0].ord == ?C.ord
6
6
  else
7
- @buffer[0].ord == ?C.ord
7
+ @compressed = @buffer[0].ord == ?C.ord
8
8
  end
9
9
  end
10
10
 
@@ -1,4 +1,23 @@
1
1
  module Conversions
2
+ def to_s
3
+ "#{@file} #{@width}x#{@height} #{@frame_rate}fps"
4
+ end
5
+
6
+ def to_hash
7
+ { :file => @file,
8
+ :signature => @signature,
9
+ :version => @version,
10
+ :avm_version => @avm_version,
11
+ :size => @size,
12
+ :bit_count => @bit_count,
13
+ :xmax => @xmax,
14
+ :ymax => @ymax,
15
+ :width => @width,
16
+ :height => @height,
17
+ :frame_rate => @frame_rate,
18
+ :frame_count => @frame_count }
19
+ end
20
+
2
21
  module Twips
3
22
  def self.from_pixels(pixels)
4
23
  pixels * 20
@@ -10,21 +29,4 @@ module Conversions
10
29
  twips / 20
11
30
  end
12
31
  end
13
-
14
- module Hash
15
- def self.from_swf_header(header)
16
- { file: header.file,
17
- signature: header.signature,
18
- version: header.version,
19
- avm_version: header.avm_version,
20
- size: header.size,
21
- bit_count: header.bit_count,
22
- xmax: header.xmax,
23
- ymax: header.ymax,
24
- width: header.width,
25
- height: header.height,
26
- frame_rate: header.frame_rate,
27
- frame_count: header.frame_count }
28
- end
29
- end
30
32
  end
@@ -1,54 +1,47 @@
1
- # TODO: Needs refactoring & cleanup
2
-
3
1
  class PackedBitObject
4
2
  attr_accessor :bitIndex, :byteIndex, :value, :nextBitIndex, :nextByteIndex, :nextByteBoundary
5
3
 
6
- def initialize(bitMarker,byteMarker,decimalValue)
7
- @bitIndex = bitMarker;
8
- @byteIndex = byteMarker;
9
- @value = decimalValue;
10
- @nextBitIndex = bitMarker;
11
- if ( bitMarker <= 7 )
12
- @nextBitIndex+=1
13
- @nextByteIndex =byteMarker
14
- @nextByteBoundary = (byteMarker+=1)
4
+ def initialize(bitMarker, byteMarker, decimalValue)
5
+ @nextBitIndex = @bitIndex = bitMarker
6
+ @byteIndex = byteMarker
7
+ @value = decimalValue
8
+
9
+ if bitMarker <= 7
10
+ @nextBitIndex += 1
11
+ @nextByteIndex = byteMarker
12
+ @nextByteBoundary = byteMarker += 1
15
13
  else
16
- @nextBitIndex = 0
17
- @nextByteIndex+=1
14
+ @nextBitIndex = 0
15
+ @nextByteIndex +=1
18
16
  @nextByteBoundary = @nextByteIndex;
19
17
  end
20
18
  end
21
19
 
22
20
  def self.from_packed_bits(bytes, byte_marker, bit_marker, length)
23
- total = 0
24
- shift = 7 - bit_marker
25
- counter = 0
26
- bit_index = bit_marker
27
- byte_index = byte_marker
21
+ counter = total = 0
22
+ shift = 7 - bit_marker
23
+ bit_index = bit_marker
24
+ byte_index = byte_marker
28
25
 
29
- while counter<length
26
+ while counter < length
30
27
  (bit_marker...8).each do |i|
31
- bit =((bytes[byte_marker].ord & 0xff ) >> shift ) & 1
32
- total = ( total << 1 ) + bit
28
+ bit = ((bytes[byte_marker].ord & 0xff ) >> shift) & 1
29
+ total = (total << 1) + bit
33
30
  bit_index = i
34
- shift-=1
35
- counter+=1
31
+ shift -= 1
32
+ counter += 1
36
33
 
37
- if counter==length
38
- break
39
- end
34
+ break if counter == length
40
35
  end
41
36
 
42
- byte_index = byte_marker
43
- byte_marker+=1
44
- bit_marker = 0
45
- shift = 7
37
+ byte_index = byte_marker
38
+ byte_marker +=1
39
+ bit_marker = 0
40
+ shift = 7
46
41
  end
47
42
 
48
43
  pbo = PackedBitObject.new(bit_index, byte_index, total)
49
-
50
44
  yield pbo if block_given?
51
-
52
45
  pbo
53
46
  end
54
47
  end
@@ -1,2 +1,48 @@
1
1
  module Parser
2
+ private
3
+ def parse_header
4
+ @buffer, @size = get_swf_buffer_and_size
5
+ raise RuntimeError, "The provided file does not appear to be an SWF", caller unless swf?
6
+
7
+ @signature = @buffer[0,3]
8
+ @version = @buffer[3].ord
9
+
10
+ decompress_buffer! if compressed?
11
+
12
+ @bit_count = ((@buffer[8].ord & 0xff) >> 3)
13
+ end
14
+
15
+ def parse_packed_bits
16
+ PackedBitObject.from_packed_bits(@buffer, 8, 5, @bit_count) do |pbo|
17
+
18
+ PackedBitObject.from_packed_bits(@buffer, pbo.nextByteIndex, pbo.nextBitIndex, @bit_count) do |pbo2|
19
+ @xmax = pbo2.value
20
+
21
+ PackedBitObject.from_packed_bits(@buffer, pbo2.nextByteIndex, pbo2.nextBitIndex, @bit_count) do |pbo3|
22
+
23
+ PackedBitObject.from_packed_bits(@buffer, pbo3.nextByteIndex, pbo3.nextBitIndex, @bit_count) do |pbo4|
24
+ @ymax = pbo4.value
25
+ @width = Conversions::Pixels.from_twips @xmax
26
+ @height = Conversions::Pixels.from_twips @ymax
27
+
28
+ byte_pointer = pbo4.nextByteIndex + 2
29
+
30
+ @frame_rate = @buffer[byte_pointer].ord
31
+ byte_pointer += 1
32
+
33
+ fc1 = @buffer[byte_pointer].ord & 0xFF
34
+ byte_pointer += 1
35
+
36
+ fc2 = @buffer[byte_pointer].ord & 0xFF
37
+ byte_pointer += 1
38
+
39
+ @frame_count = (fc2 << 8) + fc1
40
+ byte_pointer+=2
41
+
42
+ @avm_version = ((@buffer[byte_pointer].ord & 0x08) == 0) ? "AVM1" : "AVM2"
43
+ end #pbo4
44
+ end #pbo3
45
+ end #pbo2
46
+ end #pbo
47
+ end
2
48
  end
@@ -1,5 +1,8 @@
1
1
  class SwfHeader
2
+ include Parser
2
3
  include Compression
4
+ include Conversions
5
+ include Assertions
3
6
 
4
7
  attr_reader :file, :signature, :version, :avm_version, :size, :bit_count,
5
8
  :xmax, :ymax, :width, :height,
@@ -10,73 +13,17 @@ class SwfHeader
10
13
  parse_header
11
14
  parse_packed_bits
12
15
  end
13
-
14
- def compressed?(memoize_result = true)
15
- buffer_compressed?(memoize_result)
16
- end
17
-
16
+
18
17
  # Returns the duration in milliseconds
18
+ # The formula used in this method used to be +((@frame_count / @frame_rate.to_f).round(5) * 1000).round+.
19
+ # This however, was not compatible with ruby 1.8, thus reverted to its current form.
19
20
  def duration
20
- ((@frame_count / @frame_rate.to_f).round(5) * 1000).round
21
- end
22
-
23
- def to_s
24
- "#{@file} #{@width}x#{@height} #{@frame_rate}fps"
25
- end
26
-
27
- def to_hash
28
- Conversions::Hash.from_swf_header self
21
+ ((@frame_count / @frame_rate.to_f * 10**5).round.to_f / 10**5 * 1000).round
29
22
  end
30
23
 
31
24
  alias :inspect :to_hash
32
25
 
33
26
  private
34
- def parse_header
35
- @buffer, @size = get_swf_buffer_and_size
36
- raise RuntimeError, "The provided file does not appear to be an SWF", caller unless swf?
37
-
38
- @signature = @buffer[0,3]
39
- @version = @buffer[3].ord
40
-
41
- decompress_buffer! if compressed?
42
-
43
- @bit_count = ((@buffer[8].ord & 0xff) >> 3)
44
- end
45
-
46
- def parse_packed_bits
47
- PackedBitObject.from_packed_bits(@buffer, 8, 5, @bit_count) do |pbo|
48
-
49
- PackedBitObject.from_packed_bits(@buffer, pbo.nextByteIndex, pbo.nextBitIndex, @bit_count) do |pbo2|
50
- @xmax = pbo2.value
51
-
52
- PackedBitObject.from_packed_bits(@buffer, pbo2.nextByteIndex, pbo2.nextBitIndex, @bit_count) do |pbo3|
53
-
54
- PackedBitObject.from_packed_bits(@buffer, pbo3.nextByteIndex, pbo3.nextBitIndex, @bit_count) do |pbo4|
55
- @ymax = pbo4.value
56
- @width = Conversions::Pixels.from_twips @xmax
57
- @height = Conversions::Pixels.from_twips @ymax
58
-
59
- byte_pointer = pbo4.nextByteIndex + 2
60
-
61
- @frame_rate = @buffer[byte_pointer].ord
62
- byte_pointer += 1
63
-
64
- fc1 = @buffer[byte_pointer].ord & 0xFF
65
- byte_pointer += 1
66
-
67
- fc2 = @buffer[byte_pointer].ord & 0xFF
68
- byte_pointer += 1
69
-
70
- @frame_count = (fc2 << 8) + fc1
71
- byte_pointer+=2
72
-
73
- @avm_version = ((@buffer[byte_pointer].ord & 0x08) == 0) ? "AVM1" : "AVM2"
74
- end #pbo4
75
- end #pbo3
76
- end #pbo2
77
- end #pbo
78
- end
79
-
80
27
  def get_swf_buffer_and_size
81
28
  size = 0
82
29
 
@@ -90,8 +37,4 @@ class SwfHeader
90
37
 
91
38
  [buffer, size]
92
39
  end
93
-
94
- def swf?
95
- @buffer[0,3] == 'FWS' || @buffer[0,3] == 'CWS'
96
- end
97
40
  end
data/lib/swf_file.rb CHANGED
@@ -4,17 +4,33 @@ require 'zlib'
4
4
  require 'parser'
5
5
  require 'compression'
6
6
  require 'conversions'
7
+ require 'assertions'
7
8
  require 'packed_bit_object'
8
9
  require 'swf_header'
9
10
 
10
11
  class SwfFile
11
- def initialize(swf_path)
12
+ # Class methods
13
+ def self.header(swf_path)
12
14
  raise RuntimeError, "SWF file not found.", caller unless File.exists?(swf_path)
15
+
16
+ header = SwfHeader.new(swf_path)
17
+ yield(header) if block_given?
18
+ header
13
19
  end
14
20
 
15
- def self.header(swf_path)
21
+ # Instance methods
22
+ def initialize(swf_path)
16
23
  raise RuntimeError, "SWF file not found.", caller unless File.exists?(swf_path)
17
24
 
18
- SwfHeader.new(swf_path)
25
+ @header = SwfHeader.new(swf_path)
26
+ end
27
+
28
+ def header
29
+ yield(@header) if block_given?
30
+ @header
31
+ end
32
+
33
+ def compressed?
34
+ @header.compressed?
19
35
  end
20
36
  end
data/swf_file.gemspec ADDED
@@ -0,0 +1,59 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{swf_file}
8
+ s.version = "1.0.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["DBA"]
12
+ s.date = %q{2010-05-08}
13
+ s.description = %q{Based on the swfutil lib, by Dennis Zhuang, the SWF File is lightweight gem to read swf file headers from within a Ruby application. This gem is fully written in Ruby and is compatible with Ruby v1.9.x}
14
+ s.email = %q{dba@gnomeslab.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".gitignore",
21
+ "LICENSE",
22
+ "README.rdoc",
23
+ "Rakefile",
24
+ "VERSION",
25
+ "fixtures/clicktag-decompressed.swf",
26
+ "fixtures/clicktag.swf",
27
+ "fixtures/smallgoat.jpg",
28
+ "lib/swf_file.rb",
29
+ "lib/swf_file/assertions.rb",
30
+ "lib/swf_file/compression.rb",
31
+ "lib/swf_file/conversions.rb",
32
+ "lib/swf_file/packed_bit_object.rb",
33
+ "lib/swf_file/parser.rb",
34
+ "lib/swf_file/swf_header.rb",
35
+ "swf_file.gemspec",
36
+ "test/test_helper.rb",
37
+ "test/unit/swf_file_test.rb"
38
+ ]
39
+ s.homepage = %q{http://github.com/DBA/swf_file}
40
+ s.rdoc_options = ["--charset=UTF-8"]
41
+ s.require_paths = ["lib"]
42
+ s.rubygems_version = %q{1.3.7}
43
+ s.summary = %q{SWF File is lightweight gem to read swf file headers from within a Ruby application}
44
+ s.test_files = [
45
+ "test/test_helper.rb",
46
+ "test/unit/swf_file_test.rb"
47
+ ]
48
+
49
+ if s.respond_to? :specification_version then
50
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
51
+ s.specification_version = 3
52
+
53
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
54
+ else
55
+ end
56
+ else
57
+ end
58
+ end
59
+
data/test/test_helper.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
2
 
3
+ require 'rubygems' if RUBY_VERSION =~ /1\.8.+/
3
4
  require 'test/unit'
4
5
  require 'shoulda'
5
- #require 'swfheader'
6
6
  require 'ruby-debug'
7
7
  require 'swf_file'
8
8
 
@@ -1,9 +1,11 @@
1
- require_relative '../test_helper'
1
+ $:.unshift(File.join(File.dirname(__FILE__), '../', '../', 'test'))
2
+
3
+ require 'test_helper'
2
4
 
3
5
  class SwfFileTest < Test::Unit::TestCase
4
6
 
5
7
  context "SwfFile" do
6
- context "Initialization" do
8
+ context "instance methods" do
7
9
  should "not be initializable without an SWF file path" do
8
10
  assert_raise(ArgumentError) { SwfFile.new }
9
11
  end
@@ -11,7 +13,14 @@ class SwfFileTest < Test::Unit::TestCase
11
13
  should "raise an error if an invalid path is provided" do
12
14
  assert_raise(RuntimeError) { SwfFile.new "/path_to_imaginary_file" }
13
15
  end
14
- end # Initialization context
16
+
17
+ should "return a header with the regular properties" do
18
+ swf = SwfFile.new fixture_path('clicktag.swf')
19
+ assert_equal SwfHeader, swf.header.class
20
+ assert_equal 4156, swf.header.size
21
+ assert_equal swf.compressed?, swf.header.compressed?
22
+ end
23
+ end # instance methods
15
24
 
16
25
  context "class method header" do
17
26
  should "raise an error when not provided with an SWF" do
@@ -32,18 +41,18 @@ class SwfFileTest < Test::Unit::TestCase
32
41
 
33
42
  should "state if the swf was originally compressed" do
34
43
  assert @header.compressed?
35
- refute SwfFile.header(fixture_path('clicktag-decompressed.swf')).compressed?
44
+ assert !SwfFile.header(fixture_path('clicktag-decompressed.swf')).compressed?
36
45
  end
37
46
 
38
47
  should "not make available private compression module methods" do
39
48
  %w{ :buffer_compressed? :strip_buffer_header :decompress_buffer! }.each do |method|
40
- refute @header.respond_to?(method)
49
+ assert !@header.respond_to?(method)
41
50
  end
42
51
  end
43
52
 
44
53
  should "state if its buffer is currently compressed" do
45
54
  assert @header.compressed?
46
- refute @header.compressed?(false)
55
+ assert !@header.compressed?(false)
47
56
  end
48
57
 
49
58
  should "have the version" do
metadata CHANGED
@@ -3,10 +3,10 @@ name: swf_file
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
- - 0
7
6
  - 1
8
7
  - 0
9
- version: 0.1.0
8
+ - 0
9
+ version: 1.0.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - DBA
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-05-06 00:00:00 +01:00
17
+ date: 2010-05-08 00:00:00 +01:00
18
18
  default_executable:
19
19
  dependencies: []
20
20
 
@@ -26,22 +26,24 @@ extensions: []
26
26
 
27
27
  extra_rdoc_files:
28
28
  - LICENSE
29
- - README
29
+ - README.rdoc
30
30
  files:
31
31
  - .gitignore
32
32
  - LICENSE
33
- - README
33
+ - README.rdoc
34
34
  - Rakefile
35
35
  - VERSION
36
36
  - fixtures/clicktag-decompressed.swf
37
37
  - fixtures/clicktag.swf
38
38
  - fixtures/smallgoat.jpg
39
39
  - lib/swf_file.rb
40
+ - lib/swf_file/assertions.rb
40
41
  - lib/swf_file/compression.rb
41
42
  - lib/swf_file/conversions.rb
42
43
  - lib/swf_file/packed_bit_object.rb
43
44
  - lib/swf_file/parser.rb
44
45
  - lib/swf_file/swf_header.rb
46
+ - swf_file.gemspec
45
47
  - test/test_helper.rb
46
48
  - test/unit/swf_file_test.rb
47
49
  has_rdoc: true