origami 1.0.2
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/COPYING.LESSER +165 -0
- data/README +77 -0
- data/VERSION +1 -0
- data/bin/config/pdfcop.conf.yml +237 -0
- data/bin/gui/about.rb +46 -0
- data/bin/gui/config.rb +132 -0
- data/bin/gui/file.rb +385 -0
- data/bin/gui/hexdump.rb +74 -0
- data/bin/gui/hexview.rb +91 -0
- data/bin/gui/imgview.rb +72 -0
- data/bin/gui/menu.rb +392 -0
- data/bin/gui/properties.rb +132 -0
- data/bin/gui/signing.rb +635 -0
- data/bin/gui/textview.rb +107 -0
- data/bin/gui/treeview.rb +409 -0
- data/bin/gui/walker.rb +282 -0
- data/bin/gui/xrefs.rb +79 -0
- data/bin/pdf2graph +121 -0
- data/bin/pdf2ruby +353 -0
- data/bin/pdfcocoon +104 -0
- data/bin/pdfcop +455 -0
- data/bin/pdfdecompress +104 -0
- data/bin/pdfdecrypt +95 -0
- data/bin/pdfencrypt +112 -0
- data/bin/pdfextract +221 -0
- data/bin/pdfmetadata +123 -0
- data/bin/pdfsh +13 -0
- data/bin/pdfwalker +7 -0
- data/bin/shell/.irbrc +104 -0
- data/bin/shell/console.rb +136 -0
- data/bin/shell/hexdump.rb +83 -0
- data/origami.rb +36 -0
- data/origami/3d.rb +239 -0
- data/origami/acroform.rb +321 -0
- data/origami/actions.rb +299 -0
- data/origami/adobe/fdf.rb +259 -0
- data/origami/adobe/ppklite.rb +489 -0
- data/origami/annotations.rb +775 -0
- data/origami/array.rb +187 -0
- data/origami/boolean.rb +101 -0
- data/origami/catalog.rb +486 -0
- data/origami/destinations.rb +213 -0
- data/origami/dictionary.rb +188 -0
- data/origami/docmdp.rb +96 -0
- data/origami/encryption.rb +1293 -0
- data/origami/export.rb +283 -0
- data/origami/file.rb +222 -0
- data/origami/filters.rb +250 -0
- data/origami/filters/ascii.rb +189 -0
- data/origami/filters/ccitt.rb +515 -0
- data/origami/filters/crypt.rb +47 -0
- data/origami/filters/dct.rb +61 -0
- data/origami/filters/flate.rb +112 -0
- data/origami/filters/jbig2.rb +63 -0
- data/origami/filters/jpx.rb +53 -0
- data/origami/filters/lzw.rb +195 -0
- data/origami/filters/predictors.rb +276 -0
- data/origami/filters/runlength.rb +117 -0
- data/origami/font.rb +209 -0
- data/origami/functions.rb +93 -0
- data/origami/graphics.rb +33 -0
- data/origami/graphics/colors.rb +191 -0
- data/origami/graphics/instruction.rb +126 -0
- data/origami/graphics/path.rb +154 -0
- data/origami/graphics/patterns.rb +180 -0
- data/origami/graphics/state.rb +164 -0
- data/origami/graphics/text.rb +224 -0
- data/origami/graphics/xobject.rb +493 -0
- data/origami/header.rb +90 -0
- data/origami/linearization.rb +318 -0
- data/origami/metadata.rb +114 -0
- data/origami/name.rb +170 -0
- data/origami/null.rb +75 -0
- data/origami/numeric.rb +188 -0
- data/origami/obfuscation.rb +233 -0
- data/origami/object.rb +527 -0
- data/origami/outline.rb +59 -0
- data/origami/page.rb +559 -0
- data/origami/parser.rb +268 -0
- data/origami/parsers/fdf.rb +45 -0
- data/origami/parsers/pdf.rb +27 -0
- data/origami/parsers/pdf/linear.rb +113 -0
- data/origami/parsers/ppklite.rb +86 -0
- data/origami/pdf.rb +1144 -0
- data/origami/reference.rb +113 -0
- data/origami/signature.rb +474 -0
- data/origami/stream.rb +575 -0
- data/origami/string.rb +416 -0
- data/origami/trailer.rb +173 -0
- data/origami/webcapture.rb +87 -0
- data/origami/xfa.rb +3027 -0
- data/origami/xreftable.rb +447 -0
- data/templates/patterns.rb +66 -0
- data/templates/widgets.rb +173 -0
- data/templates/xdp.rb +92 -0
- data/tests/dataset/test.dummycrt +28 -0
- data/tests/dataset/test.dummykey +27 -0
- data/tests/tc_actions.rb +32 -0
- data/tests/tc_annotations.rb +85 -0
- data/tests/tc_pages.rb +37 -0
- data/tests/tc_pdfattach.rb +24 -0
- data/tests/tc_pdfencrypt.rb +110 -0
- data/tests/tc_pdfnew.rb +32 -0
- data/tests/tc_pdfparse.rb +98 -0
- data/tests/tc_pdfsig.rb +37 -0
- data/tests/tc_streams.rb +129 -0
- data/tests/ts_pdf.rb +45 -0
- metadata +193 -0
@@ -0,0 +1,47 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
= File
|
4
|
+
filters/crypt.rb
|
5
|
+
|
6
|
+
= Info
|
7
|
+
This file is part of Origami, PDF manipulation framework for Ruby
|
8
|
+
Copyright (C) 2010 Guillaume Delugré <guillaume@security-labs.org>
|
9
|
+
All right reserved.
|
10
|
+
|
11
|
+
Origami is free software: you can redistribute it and/or modify
|
12
|
+
it under the terms of the GNU Lesser General Public License as published by
|
13
|
+
the Free Software Foundation, either version 3 of the License, or
|
14
|
+
(at your option) any later version.
|
15
|
+
|
16
|
+
Origami is distributed in the hope that it will be useful,
|
17
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
18
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
19
|
+
GNU Lesser General Public License for more details.
|
20
|
+
|
21
|
+
You should have received a copy of the GNU Lesser General Public License
|
22
|
+
along with Origami. If not, see <http://www.gnu.org/licenses/>.
|
23
|
+
|
24
|
+
=end
|
25
|
+
|
26
|
+
module Origami
|
27
|
+
|
28
|
+
module Filter
|
29
|
+
|
30
|
+
#
|
31
|
+
# Class representing a Crypt Filter.
|
32
|
+
# TODO.
|
33
|
+
#
|
34
|
+
class Crypt
|
35
|
+
include Filter
|
36
|
+
|
37
|
+
class DecodeParms < Dictionary
|
38
|
+
include StandardObject
|
39
|
+
|
40
|
+
field :Type, :Type => Name, :Default => :Crypt
|
41
|
+
field :Name, :Type => Name, :Default => :Identity
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
@@ -0,0 +1,61 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
= File
|
4
|
+
filters/dct.rb
|
5
|
+
|
6
|
+
= Info
|
7
|
+
This file is part of Origami, PDF manipulation framework for Ruby
|
8
|
+
Copyright (C) 2010 Guillaume Delugré <guillaume@security-labs.org>
|
9
|
+
All right reserved.
|
10
|
+
|
11
|
+
Origami is free software: you can redistribute it and/or modify
|
12
|
+
it under the terms of the GNU Lesser General Public License as published by
|
13
|
+
the Free Software Foundation, either version 3 of the License, or
|
14
|
+
(at your option) any later version.
|
15
|
+
|
16
|
+
Origami is distributed in the hope that it will be useful,
|
17
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
18
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
19
|
+
GNU Lesser General Public License for more details.
|
20
|
+
|
21
|
+
You should have received a copy of the GNU Lesser General Public License
|
22
|
+
along with Origami. If not, see <http://www.gnu.org/licenses/>.
|
23
|
+
|
24
|
+
=end
|
25
|
+
|
26
|
+
module Origami
|
27
|
+
|
28
|
+
module Filter
|
29
|
+
|
30
|
+
#
|
31
|
+
# Class representing a Filter used to encode and decode data with DCT (JPEG) compression algorithm.
|
32
|
+
#
|
33
|
+
class DCT
|
34
|
+
include Filter
|
35
|
+
|
36
|
+
class DecodeParms < Dictionary
|
37
|
+
include StandardObject
|
38
|
+
|
39
|
+
field :ColorTransform, :Type => Integer
|
40
|
+
end
|
41
|
+
|
42
|
+
def initialize(parameters = {})
|
43
|
+
super(DecodeParms.new(parameters))
|
44
|
+
end
|
45
|
+
|
46
|
+
def encode(stream)
|
47
|
+
stream
|
48
|
+
end
|
49
|
+
|
50
|
+
#
|
51
|
+
# DCTDecode implies that data is a JPEG image container.
|
52
|
+
# Just returns the raw JPEG image as is.
|
53
|
+
#
|
54
|
+
def decode(stream)
|
55
|
+
stream
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
@@ -0,0 +1,112 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
= File
|
4
|
+
filters/flate.rb
|
5
|
+
|
6
|
+
= Info
|
7
|
+
This file is part of Origami, PDF manipulation framework for Ruby
|
8
|
+
Copyright (C) 2010 Guillaume Delugré <guillaume@security-labs.org>
|
9
|
+
All right reserved.
|
10
|
+
|
11
|
+
Origami is free software: you can redistribute it and/or modify
|
12
|
+
it under the terms of the GNU Lesser General Public License as published by
|
13
|
+
the Free Software Foundation, either version 3 of the License, or
|
14
|
+
(at your option) any later version.
|
15
|
+
|
16
|
+
Origami is distributed in the hope that it will be useful,
|
17
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
18
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
19
|
+
GNU Lesser General Public License for more details.
|
20
|
+
|
21
|
+
You should have received a copy of the GNU Lesser General Public License
|
22
|
+
along with Origami. If not, see <http://www.gnu.org/licenses/>.
|
23
|
+
|
24
|
+
=end
|
25
|
+
|
26
|
+
require 'zlib'
|
27
|
+
require 'origami/filters/predictors'
|
28
|
+
|
29
|
+
module Origami
|
30
|
+
|
31
|
+
module Filter
|
32
|
+
|
33
|
+
class InvalidFlateDataError < Exception #:nodoc:
|
34
|
+
attr_reader :zlib_stream, :zlib_except
|
35
|
+
|
36
|
+
def initialize(zlib_stream, zlib_except)
|
37
|
+
super(zlib_except.message)
|
38
|
+
|
39
|
+
@zlib_stream = zlib_stream
|
40
|
+
@zlib_except = zlib_except
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
#
|
45
|
+
# Class representing a Filter used to encode and decode data with zlib/Flate compression algorithm.
|
46
|
+
#
|
47
|
+
class Flate
|
48
|
+
include Filter
|
49
|
+
|
50
|
+
EOD = 257 #:nodoc:
|
51
|
+
|
52
|
+
class DecodeParms < Dictionary
|
53
|
+
include StandardObject
|
54
|
+
|
55
|
+
field :Predictor, :Type => Integer, :Default => 1
|
56
|
+
field :Colors, :Type => Integer, :Default => 1
|
57
|
+
field :BitsPerComponent, :Type => Integer, :Default => 8
|
58
|
+
field :Columns, :Type => Integer, :Default => 1
|
59
|
+
end
|
60
|
+
|
61
|
+
#
|
62
|
+
# Create a new Flate Filter.
|
63
|
+
# _parameters_:: A hash of filter options (ignored).
|
64
|
+
#
|
65
|
+
def initialize(parameters = {})
|
66
|
+
super(DecodeParms.new(parameters))
|
67
|
+
end
|
68
|
+
|
69
|
+
#
|
70
|
+
# Encodes data using zlib/Deflate compression method.
|
71
|
+
# _stream_:: The data to encode.
|
72
|
+
#
|
73
|
+
def encode(stream)
|
74
|
+
if @params.Predictor.is_a?(Integer)
|
75
|
+
colors = @params.Colors.is_a?(Integer) ? @params.Colors.to_i : 1
|
76
|
+
bpc = @params.BitsPerComponent.is_a?(Integer) ? @params.BitsPerComponent.to_i : 8
|
77
|
+
columns = @params.Columns.is_a?(Integer) ? @params.Columns.to_i : 1
|
78
|
+
|
79
|
+
stream = Predictor.do_pre_prediction(stream, @params.Predictor.to_i, colors, bpc, columns)
|
80
|
+
end
|
81
|
+
|
82
|
+
Zlib::Deflate.deflate(stream, Zlib::BEST_COMPRESSION)
|
83
|
+
end
|
84
|
+
|
85
|
+
#
|
86
|
+
# Decodes data using zlib/Inflate decompression method.
|
87
|
+
# _stream_:: The data to decode.
|
88
|
+
#
|
89
|
+
def decode(stream)
|
90
|
+
|
91
|
+
zlib_stream = Zlib::Inflate.new
|
92
|
+
begin
|
93
|
+
uncompressed = zlib_stream.inflate(stream)
|
94
|
+
rescue Zlib::DataError => zlib_except
|
95
|
+
raise InvalidFlateDataError.new(zlib_stream, zlib_except)
|
96
|
+
end
|
97
|
+
|
98
|
+
if @params.Predictor.is_a?(Integer)
|
99
|
+
colors = @params.Colors.is_a?(Integer) ? @params.Colors.to_i : 1
|
100
|
+
bpc = @params.BitsPerComponent.is_a?(Integer) ? @params.BitsPerComponent.to_i : 8
|
101
|
+
columns = @params.Columns.is_a?(Integer) ? @params.Columns.to_i : 1
|
102
|
+
|
103
|
+
uncompressed = Predictor.do_post_prediction(uncompressed, @params.Predictor.to_i, colors, bpc, columns)
|
104
|
+
end
|
105
|
+
|
106
|
+
uncompressed
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
@@ -0,0 +1,63 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
= File
|
4
|
+
filters/jbig2.rb
|
5
|
+
|
6
|
+
= Info
|
7
|
+
This file is part of Origami, PDF manipulation framework for Ruby
|
8
|
+
Copyright (C) 2010 Guillaume Delugré <guillaume@security-labs.org>
|
9
|
+
All right reserved.
|
10
|
+
|
11
|
+
Origami is free software: you can redistribute it and/or modify
|
12
|
+
it under the terms of the GNU Lesser General Public License as published by
|
13
|
+
the Free Software Foundation, either version 3 of the License, or
|
14
|
+
(at your option) any later version.
|
15
|
+
|
16
|
+
Origami is distributed in the hope that it will be useful,
|
17
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
18
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
19
|
+
GNU Lesser General Public License for more details.
|
20
|
+
|
21
|
+
You should have received a copy of the GNU Lesser General Public License
|
22
|
+
along with Origami. If not, see <http://www.gnu.org/licenses/>.
|
23
|
+
|
24
|
+
=end
|
25
|
+
|
26
|
+
module Origami
|
27
|
+
|
28
|
+
module Filter
|
29
|
+
|
30
|
+
#
|
31
|
+
# Class representing a Filter used to encode and decode data with JBIG2 compression algorithm.
|
32
|
+
#
|
33
|
+
class JBIG2
|
34
|
+
include Filter
|
35
|
+
|
36
|
+
class DecodeParms < Dictionary
|
37
|
+
include StandardObject
|
38
|
+
|
39
|
+
field :JBIG2Globals, :Type => Stream
|
40
|
+
end
|
41
|
+
|
42
|
+
def initialize(parameters = {})
|
43
|
+
super(DecodeParms.new(parameters))
|
44
|
+
end
|
45
|
+
|
46
|
+
#
|
47
|
+
# Not supported.
|
48
|
+
#
|
49
|
+
def encode(stream)
|
50
|
+
raise NotImplementedError, "#{self.class} is not yet supported"
|
51
|
+
end
|
52
|
+
|
53
|
+
#
|
54
|
+
# Not supported.
|
55
|
+
#
|
56
|
+
def decode(stream)
|
57
|
+
raise NotImplementedError, "#{self.class} is not yet supported"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
@@ -0,0 +1,53 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
= File
|
4
|
+
filters/jpx.rb
|
5
|
+
|
6
|
+
= Info
|
7
|
+
This file is part of Origami, PDF manipulation framework for Ruby
|
8
|
+
Copyright (C) 2010 Guillaume Delugré <guillaume@security-labs.org>
|
9
|
+
All right reserved.
|
10
|
+
|
11
|
+
Origami is free software: you can redistribute it and/or modify
|
12
|
+
it under the terms of the GNU Lesser General Public License as published by
|
13
|
+
the Free Software Foundation, either version 3 of the License, or
|
14
|
+
(at your option) any later version.
|
15
|
+
|
16
|
+
Origami is distributed in the hope that it will be useful,
|
17
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
18
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
19
|
+
GNU Lesser General Public License for more details.
|
20
|
+
|
21
|
+
You should have received a copy of the GNU Lesser General Public License
|
22
|
+
along with Origami. If not, see <http://www.gnu.org/licenses/>.
|
23
|
+
|
24
|
+
=end
|
25
|
+
|
26
|
+
module Origami
|
27
|
+
|
28
|
+
module Filter
|
29
|
+
|
30
|
+
#
|
31
|
+
# Class representing a Filter used to encode and decode data with JPX compression algorithm.
|
32
|
+
#
|
33
|
+
class JPX
|
34
|
+
include Filter
|
35
|
+
|
36
|
+
#
|
37
|
+
# Not supported.
|
38
|
+
#
|
39
|
+
def encode(stream)
|
40
|
+
raise NotImplementedError, "#{self.class} is not yet supported"
|
41
|
+
end
|
42
|
+
|
43
|
+
#
|
44
|
+
# Not supported.
|
45
|
+
#
|
46
|
+
def decode(stream)
|
47
|
+
raise NotImplementedError, "#{self.class} is not yet supported"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
@@ -0,0 +1,195 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
= File
|
4
|
+
filters/lzw.rb
|
5
|
+
|
6
|
+
= Info
|
7
|
+
This file is part of Origami, PDF manipulation framework for Ruby
|
8
|
+
Copyright (C) 2010 Guillaume Delugré <guillaume@security-labs.org>
|
9
|
+
All right reserved.
|
10
|
+
|
11
|
+
Origami is free software: you can redistribute it and/or modify
|
12
|
+
it under the terms of the GNU Lesser General Public License as published by
|
13
|
+
the Free Software Foundation, either version 3 of the License, or
|
14
|
+
(at your option) any later version.
|
15
|
+
|
16
|
+
Origami is distributed in the hope that it will be useful,
|
17
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
18
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
19
|
+
GNU Lesser General Public License for more details.
|
20
|
+
|
21
|
+
You should have received a copy of the GNU Lesser General Public License
|
22
|
+
along with Origami. If not, see <http://www.gnu.org/licenses/>.
|
23
|
+
|
24
|
+
=end
|
25
|
+
|
26
|
+
require 'origami/filters/predictors'
|
27
|
+
|
28
|
+
module Origami
|
29
|
+
|
30
|
+
module Filter
|
31
|
+
|
32
|
+
class InvalidLZWDataError < Exception #:nodoc:
|
33
|
+
end
|
34
|
+
|
35
|
+
#
|
36
|
+
# Class representing a filter used to encode and decode data with LZW compression algorithm.
|
37
|
+
#
|
38
|
+
class LZW
|
39
|
+
|
40
|
+
include Filter
|
41
|
+
|
42
|
+
class DecodeParms < Dictionary
|
43
|
+
include StandardObject
|
44
|
+
|
45
|
+
field :Predictor, :Type => Integer, :Default => 1
|
46
|
+
field :Colors, :Type => Integer, :Default => 1
|
47
|
+
field :BitsPerComponent, :Type => Integer, :Default => 8
|
48
|
+
field :Columns, :Type => Integer, :Default => 1
|
49
|
+
field :EarlyChange, :Type => Integer, :Default => 1
|
50
|
+
end
|
51
|
+
|
52
|
+
EOD = 257 #:nodoc:
|
53
|
+
CLEARTABLE = 256 #:nodoc:
|
54
|
+
|
55
|
+
#
|
56
|
+
# Creates a new LZW Filter.
|
57
|
+
# _parameters_:: A hash of filter options (ignored).
|
58
|
+
#
|
59
|
+
def initialize(parameters = {})
|
60
|
+
super(DecodeParms.new(parameters))
|
61
|
+
end
|
62
|
+
|
63
|
+
#
|
64
|
+
# Encodes given data using LZW compression method.
|
65
|
+
# _stream_:: The data to encode.
|
66
|
+
#
|
67
|
+
def encode(string)
|
68
|
+
if @params.Predictor.is_a?(Integer)
|
69
|
+
colors = @params.Colors.is_a?(Integer) ? @params.Colors.to_i : 1
|
70
|
+
bpc = @params.BitsPerComponent.is_a?(Integer) ? @params.BitsPerComponent.to_i : 8
|
71
|
+
columns = @params.Columns.is_a?(Integer) ? @params.Columns.to_i : 1
|
72
|
+
|
73
|
+
string = Predictor.do_pre_prediction(string, @params.Predictor.to_i, colors, bpc, columns)
|
74
|
+
end
|
75
|
+
|
76
|
+
codesize = 9
|
77
|
+
result = Utils::BitWriter.new
|
78
|
+
result.write(CLEARTABLE, codesize)
|
79
|
+
table = clear({})
|
80
|
+
|
81
|
+
s = ''
|
82
|
+
string.each_byte do |byte|
|
83
|
+
char = byte.chr
|
84
|
+
|
85
|
+
case table.size
|
86
|
+
when 512 then codesize = 10
|
87
|
+
when 1024 then codesize = 11
|
88
|
+
when 2048 then codesize = 12
|
89
|
+
when 4096
|
90
|
+
result.write(CLEARTABLE, codesize)
|
91
|
+
codesize = 9
|
92
|
+
clear table
|
93
|
+
redo
|
94
|
+
end
|
95
|
+
|
96
|
+
it = s + char
|
97
|
+
if table.has_key?(it)
|
98
|
+
s = it
|
99
|
+
else
|
100
|
+
result.write(table[s], codesize)
|
101
|
+
table[it] = table.size
|
102
|
+
s = char
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
result.write(table[s], codesize)
|
107
|
+
result.write(EOD, codesize)
|
108
|
+
|
109
|
+
result.final.to_s
|
110
|
+
end
|
111
|
+
|
112
|
+
#
|
113
|
+
# Decodes given data using LZW compression method.
|
114
|
+
# _stream_:: The data to decode.
|
115
|
+
#
|
116
|
+
def decode(string)
|
117
|
+
|
118
|
+
result = ""
|
119
|
+
bstring = Utils::BitReader.new(string)
|
120
|
+
codesize = 9
|
121
|
+
table = clear(Hash.new)
|
122
|
+
prevbyte = nil
|
123
|
+
|
124
|
+
until bstring.eod? do
|
125
|
+
byte = bstring.read(codesize)
|
126
|
+
|
127
|
+
case table.size
|
128
|
+
when 510 then codesize = 10
|
129
|
+
when 1022 then codesize = 11
|
130
|
+
when 2046 then codesize = 12
|
131
|
+
when 4095
|
132
|
+
if byte != CLEARTABLE
|
133
|
+
then
|
134
|
+
raise InvalidLZWDataError,
|
135
|
+
"LZW table is full and no clear flag was set (codeword #{byte.to_s(2).rjust(codesize,'0')} at bit #{bstring.pos - codesize}/#{bstring.size})"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
if byte == CLEARTABLE
|
140
|
+
codesize = 9
|
141
|
+
code = EOD
|
142
|
+
clear table
|
143
|
+
prevbyte = nil
|
144
|
+
redo
|
145
|
+
elsif byte == EOD
|
146
|
+
break
|
147
|
+
else
|
148
|
+
if prevbyte.nil?
|
149
|
+
prevbyte = byte
|
150
|
+
result << table.key(byte)
|
151
|
+
redo
|
152
|
+
else
|
153
|
+
if table.has_value?(byte)
|
154
|
+
entry = table.key(byte)
|
155
|
+
else
|
156
|
+
entry = table.key(prevbyte)
|
157
|
+
entry += entry[0,1]
|
158
|
+
end
|
159
|
+
|
160
|
+
result << entry
|
161
|
+
table[table.key(prevbyte) + entry[0,1]] = table.size
|
162
|
+
prevbyte = byte
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
if @params.Predictor.is_a?(Integer)
|
168
|
+
colors = @params.Colors.is_a?(Integer) ? @params.Colors.to_i : 1
|
169
|
+
bpc = @params.BitsPerComponent.is_a?(Integer) ? @params.BitsPerComponent.to_i : 8
|
170
|
+
columns = @params.Columns.is_a?(Integer) ? @params.Columns.to_i : 1
|
171
|
+
|
172
|
+
result = Predictor.do_post_prediction(result, @params.Predictor.to_i, colors, bpc, columns)
|
173
|
+
end
|
174
|
+
|
175
|
+
result
|
176
|
+
end
|
177
|
+
|
178
|
+
private
|
179
|
+
|
180
|
+
def clear(table) #:nodoc:
|
181
|
+
table.clear
|
182
|
+
256.times do |i|
|
183
|
+
table[i.chr] = i
|
184
|
+
end
|
185
|
+
|
186
|
+
table[CLEARTABLE] = CLEARTABLE
|
187
|
+
table[EOD] = EOD
|
188
|
+
|
189
|
+
table
|
190
|
+
end
|
191
|
+
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|