gif-info 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,32 @@
1
+ # encoding: utf-8
2
+ # (c) 2011 Martin Kozák (martinkozak@martinkozak.net)
3
+
4
+ require "gif-info/block"
5
+
6
+ ##
7
+ # Primary GifInfo module.
8
+ #
9
+
10
+ class GifInfo
11
+
12
+ ##
13
+ # General blocks module.
14
+ #
15
+
16
+ module Blocks
17
+
18
+ ##
19
+ # Indicates the end of the file.
20
+ #
21
+
22
+ class Trailer < Block
23
+ ##
24
+ # Skips block in stream.
25
+ #
26
+
27
+ def skip!
28
+ @io.seek(1, IO::SEEK_CUR)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,105 @@
1
+ # encoding: utf-8
2
+ # (c) 2011 Martin Kozák (martinkozak@martinkozak.net)
3
+
4
+ ##
5
+ # Primary GifInfo module.
6
+ #
7
+
8
+ class GifInfo
9
+
10
+ ##
11
+ # Decoder and holder of block-encoded GIF data.
12
+ #
13
+
14
+ class Body
15
+
16
+ ##
17
+ # IO object.
18
+ #
19
+
20
+ @io
21
+
22
+ ##
23
+ # Position in stream.
24
+ #
25
+
26
+ @position
27
+
28
+ ##
29
+ # Data contained in the data body.
30
+ #
31
+
32
+ @data
33
+
34
+ ##
35
+ # Constructor.
36
+ # @param [IO] io IO object
37
+ #
38
+
39
+ def initialize(io)
40
+ @io = io
41
+ @position = io.pos
42
+ end
43
+
44
+ ##
45
+ # Returns data.
46
+ # If block given, streams it, in otherwise returns full value.
47
+ #
48
+ # @yield [String] chunk in size of one data block of the raw data
49
+ # @return [String] full data content
50
+ #
51
+
52
+ def data(&block)
53
+ if not @data.nil?
54
+ return @data
55
+ end
56
+
57
+ self.prepare! # seeks to block position
58
+
59
+ if not block.nil?
60
+ loop do
61
+ size = @io.getbyte
62
+ break if size <= 0
63
+ block.call(@io.read(size))
64
+ end
65
+ else
66
+ data = ""
67
+ self.data do |chunk|
68
+ data << chunk
69
+ end
70
+ @data = data
71
+
72
+ return @data
73
+ end
74
+ end
75
+
76
+ ##
77
+ # Skips the body content in stream.
78
+ #
79
+
80
+ def skip!
81
+ loop do
82
+ size = @io.getbyte
83
+ break if size <= 0
84
+ @io.seek(size, IO::SEEK_CUR)
85
+ end
86
+ end
87
+
88
+ ##
89
+ # Prepares for reading.
90
+ #
91
+
92
+ def prepare!
93
+ @io.seek(@position)
94
+ end
95
+
96
+ ##
97
+ # Returns bytesize of the data body.
98
+ # @return [Integer] length in bytes
99
+ #
100
+
101
+ def bytesize
102
+ self.data.bytesize
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,32 @@
1
+ # encoding: utf-8
2
+ # (c) 2011 Martin Kozák (martinkozak@martinkozak.net)
3
+
4
+ require "gif-info/raw-block"
5
+
6
+ ##
7
+ # Primary GifInfo module.
8
+ #
9
+
10
+ class GifInfo
11
+
12
+ ##
13
+ # General color table block.
14
+ # @abstract
15
+ #
16
+
17
+ class ColorTable < RawBlock
18
+
19
+ ##
20
+ # Constructor.
21
+ #
22
+ # @param [IO] io IO object
23
+ # @param [Integer] size size as it's reported by header blocks
24
+ #
25
+
26
+ def initialize(io, size)
27
+ super(io, 3 * (2 ** (size + 1)))
28
+ end
29
+
30
+ end
31
+
32
+ end
@@ -0,0 +1,56 @@
1
+ # encoding: utf-8
2
+ # (c) 2011 Martin Kozák (martinkozak@martinkozak.net)
3
+
4
+ require "gif-info/block"
5
+ require "gif-info/body"
6
+
7
+ ##
8
+ # Primary GifInfo module.
9
+ #
10
+
11
+ class GifInfo
12
+
13
+ ##
14
+ # Abstract block which contains data in {Body} form only.
15
+ # @abstract
16
+ #
17
+
18
+ class DataBlock < Block
19
+
20
+ ##
21
+ # Data body content.
22
+ #
23
+
24
+ @body
25
+
26
+ ##
27
+ # Returns data body.
28
+ # @return [Body] data body
29
+ #
30
+
31
+ def body
32
+ if @body.nil?
33
+ @body = Body::new(@io)
34
+ end
35
+
36
+ return @body
37
+ end
38
+
39
+ ##
40
+ # Skips block in stream.
41
+ #
42
+
43
+ def skip!
44
+ self.body.skip!
45
+ end
46
+
47
+ ##
48
+ # Returns block size.
49
+ # @return [Integer] block size in bytes
50
+ #
51
+
52
+ def bytesize
53
+ self.body.bytesize
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,66 @@
1
+ # encoding: utf-8
2
+ # (c) 2011 Martin Kozák (martinkozak@martinkozak.net)
3
+
4
+ require "gif-info/fixed-block"
5
+
6
+ ##
7
+ # Primary GifInfo module.
8
+ #
9
+
10
+ class GifInfo
11
+
12
+ ##
13
+ # Abstract block which contains both header and data with dynamic
14
+ # (non-fixed) length.
15
+ #
16
+ # @abstract
17
+ #
18
+
19
+ class DynamicBlock < FixedBlock
20
+
21
+ ##
22
+ # Holds data body.
23
+ #
24
+
25
+ @body
26
+
27
+ ##
28
+ # Returns data body.
29
+ #
30
+ # @param [Integer] skip number of bytes to skip before data
31
+ # @return [Body] data body
32
+ #
33
+
34
+ def body(skip = nil)
35
+ if @body.nil?
36
+ if not skip.nil?
37
+ @io.seek(skip, IO::SEEK_CUR) # skips dummy leader
38
+ end
39
+ @body = Body::new(@io)
40
+ end
41
+
42
+ @body
43
+ end
44
+
45
+ ##
46
+ # Skips block in stream.
47
+ #
48
+
49
+ def skip!(additional = nil)
50
+ super()
51
+ if not additional.nil?
52
+ @io.seek(additional, IO::SEEK_CUR)
53
+ end
54
+ self.body.skip!
55
+ end
56
+
57
+ ##
58
+ # Returns block size.
59
+ # @return [Integer] block size in bytes
60
+ #
61
+
62
+ def bytesize
63
+ self.header.bytesize + self.body.bytesize
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,82 @@
1
+ # encoding: utf-8
2
+ # (c) 2011 Martin Kozák (martinkozak@martinkozak.net)
3
+
4
+ require "struct-fx" # 0.1.1
5
+ require "gif-info/block"
6
+
7
+ ##
8
+ # Primary GifInfo module.
9
+ #
10
+
11
+ class GifInfo
12
+
13
+ ##
14
+ # Abstract fixed-size block which contains header only.
15
+ # @abstract
16
+ #
17
+
18
+ class FixedBlock < Block
19
+
20
+ ##
21
+ # Holds header.
22
+ #
23
+
24
+ @header
25
+
26
+ ##
27
+ # Holds header struct.
28
+ #
29
+ # In case, data are loaded, @header and @struct links to the
30
+ # same objects.
31
+ #
32
+
33
+ @struct
34
+
35
+ ##
36
+ # Returns header struct.
37
+ # @return [StructFx] struct
38
+ #
39
+
40
+ def header
41
+ if @header.nil?
42
+ self.prepare!
43
+ @header = __struct
44
+ @header << @io.read(@header.bytesize)
45
+ end
46
+
47
+ @header
48
+ end
49
+
50
+ ##
51
+ # Skips block in stream.
52
+ #
53
+
54
+ def skip!
55
+ @io.seek(__struct.bytesize, IO::SEEK_CUR)
56
+ end
57
+
58
+ ##
59
+ # Returns block size.
60
+ # @return [Integer] block size in bytes
61
+ #
62
+
63
+ def bytesize
64
+ self.header.bytesize
65
+ end
66
+
67
+
68
+ private
69
+
70
+ ##
71
+ # Returns header struct.
72
+ #
73
+
74
+ def __struct
75
+ if @struct.nil?
76
+ @struct = StructFx::new(&self.class::STRUCTURE)
77
+ end
78
+
79
+ @struct
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,78 @@
1
+ # encoding: utf-8
2
+ # (c) 2011 Martin Kozák (martinkozak@martinkozak.net)
3
+
4
+ require "gif-info/block"
5
+
6
+ ##
7
+ # Primary GifInfo module.
8
+ #
9
+
10
+ class GifInfo
11
+
12
+ ##
13
+ # Abstract block which contains only datas in non-formatted form,
14
+ # so data which aren't encoded in block form as usuall in GIF.
15
+ # Typicall example are color tables which site is known in forward.
16
+ #
17
+ # @abstract
18
+ #
19
+
20
+ class RawBlock < Block
21
+
22
+ ##
23
+ # Data body of block.
24
+ #
25
+
26
+ @body
27
+
28
+ ##
29
+ # Indicates length of the data for read.
30
+ #
31
+
32
+ @size
33
+
34
+ ##
35
+ # Constructor.
36
+ #
37
+ # @param [IO] io IO object
38
+ # @param [Integer] size amount of data for read
39
+ #
40
+
41
+ def initialize(io, size)
42
+ @size = size
43
+ super(io)
44
+ end
45
+
46
+ ##
47
+ # Returns data body.
48
+ # @return [String] raw data
49
+ #
50
+
51
+ def body
52
+ if @body.nil?
53
+ self.prepare!
54
+ @body = @io.read(@size)
55
+ end
56
+
57
+ return @body
58
+ end
59
+
60
+ ##
61
+ # Skips block in stream.
62
+ #
63
+
64
+ def skip!
65
+ @io.seek(@size, IO::SEEK_CUR)
66
+ end
67
+
68
+ ##
69
+ # Returns block size.
70
+ # @return [Integer] block size in bytes
71
+ #
72
+
73
+ def bytesize
74
+ self.body.bytesize
75
+ end
76
+ end
77
+ end
78
+