origami 1.2.7 → 2.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +66 -0
- data/README.md +112 -0
- data/bin/config/pdfcop.conf.yml +232 -233
- data/bin/gui/about.rb +27 -37
- data/bin/gui/config.rb +108 -117
- data/bin/gui/file.rb +416 -365
- data/bin/gui/gtkhex.rb +1138 -1153
- data/bin/gui/hexview.rb +55 -57
- data/bin/gui/imgview.rb +48 -51
- data/bin/gui/menu.rb +388 -386
- data/bin/gui/properties.rb +114 -130
- data/bin/gui/signing.rb +571 -617
- data/bin/gui/textview.rb +77 -95
- data/bin/gui/treeview.rb +382 -387
- data/bin/gui/walker.rb +227 -232
- data/bin/gui/xrefs.rb +56 -60
- data/bin/pdf2pdfa +53 -57
- data/bin/pdf2ruby +212 -228
- data/bin/pdfcop +338 -348
- data/bin/pdfdecompress +58 -65
- data/bin/pdfdecrypt +56 -60
- data/bin/pdfencrypt +75 -80
- data/bin/pdfexplode +185 -182
- data/bin/pdfextract +201 -218
- data/bin/pdfmetadata +83 -82
- data/bin/pdfsh +4 -5
- data/bin/pdfwalker +1 -2
- data/bin/shell/.irbrc +45 -82
- data/bin/shell/console.rb +105 -130
- data/bin/shell/hexdump.rb +40 -64
- data/examples/README.md +34 -0
- data/examples/attachments/attachment.rb +38 -0
- data/examples/attachments/nested_document.rb +51 -0
- data/examples/encryption/encryption.rb +28 -0
- data/{samples/actions/triggerevents/trigger.rb → examples/events/events.rb} +13 -16
- data/examples/flash/flash.rb +37 -0
- data/{samples → examples}/flash/helloworld.swf +0 -0
- data/examples/forms/javascript.rb +54 -0
- data/examples/forms/xfa.rb +115 -0
- data/examples/javascript/hello_world.rb +22 -0
- data/examples/javascript/js_emulation.rb +54 -0
- data/examples/loop/goto.rb +32 -0
- data/examples/loop/named.rb +33 -0
- data/examples/signature/signature.rb +65 -0
- data/examples/uri/javascript.rb +56 -0
- data/examples/uri/open-uri.rb +21 -0
- data/examples/uri/submitform.rb +47 -0
- data/lib/origami.rb +29 -42
- data/lib/origami/3d.rb +350 -225
- data/lib/origami/acroform.rb +262 -288
- data/lib/origami/actions.rb +268 -288
- data/lib/origami/annotations.rb +697 -722
- data/lib/origami/array.rb +258 -184
- data/lib/origami/boolean.rb +74 -84
- data/lib/origami/catalog.rb +397 -434
- data/lib/origami/collections.rb +144 -0
- data/lib/origami/destinations.rb +233 -194
- data/lib/origami/dictionary.rb +253 -232
- data/lib/origami/encryption.rb +1274 -1243
- data/lib/origami/export.rb +232 -268
- data/lib/origami/extensions/fdf.rb +307 -220
- data/lib/origami/extensions/ppklite.rb +368 -435
- data/lib/origami/filespec.rb +197 -0
- data/lib/origami/filters.rb +301 -295
- data/lib/origami/filters/ascii.rb +177 -180
- data/lib/origami/filters/ccitt.rb +528 -535
- data/lib/origami/filters/crypt.rb +26 -35
- data/lib/origami/filters/dct.rb +46 -52
- data/lib/origami/filters/flate.rb +95 -94
- data/lib/origami/filters/jbig2.rb +49 -55
- data/lib/origami/filters/jpx.rb +38 -44
- data/lib/origami/filters/lzw.rb +189 -183
- data/lib/origami/filters/predictors.rb +221 -235
- data/lib/origami/filters/runlength.rb +103 -104
- data/lib/origami/font.rb +173 -186
- data/lib/origami/functions.rb +67 -81
- data/lib/origami/graphics.rb +25 -21
- data/lib/origami/graphics/colors.rb +178 -187
- data/lib/origami/graphics/instruction.rb +79 -85
- data/lib/origami/graphics/path.rb +142 -148
- data/lib/origami/graphics/patterns.rb +160 -167
- data/lib/origami/graphics/render.rb +43 -50
- data/lib/origami/graphics/state.rb +138 -153
- data/lib/origami/graphics/text.rb +188 -205
- data/lib/origami/graphics/xobject.rb +819 -815
- data/lib/origami/header.rb +63 -78
- data/lib/origami/javascript.rb +596 -597
- data/lib/origami/linearization.rb +285 -290
- data/lib/origami/metadata.rb +139 -148
- data/lib/origami/name.rb +112 -148
- data/lib/origami/null.rb +53 -62
- data/lib/origami/numeric.rb +162 -175
- data/lib/origami/obfuscation.rb +186 -174
- data/lib/origami/object.rb +593 -573
- data/lib/origami/outline.rb +42 -47
- data/lib/origami/outputintents.rb +73 -82
- data/lib/origami/page.rb +703 -592
- data/lib/origami/parser.rb +238 -290
- data/lib/origami/parsers/fdf.rb +41 -33
- data/lib/origami/parsers/pdf.rb +75 -95
- data/lib/origami/parsers/pdf/lazy.rb +137 -0
- data/lib/origami/parsers/pdf/linear.rb +64 -66
- data/lib/origami/parsers/ppklite.rb +34 -70
- data/lib/origami/pdf.rb +1030 -1005
- data/lib/origami/reference.rb +102 -102
- data/lib/origami/signature.rb +591 -609
- data/lib/origami/stream.rb +668 -551
- data/lib/origami/string.rb +397 -373
- data/lib/origami/template/patterns.rb +56 -0
- data/lib/origami/template/widgets.rb +151 -0
- data/lib/origami/trailer.rb +144 -158
- data/lib/origami/tree.rb +62 -0
- data/lib/origami/version.rb +23 -0
- data/lib/origami/webcapture.rb +88 -79
- data/lib/origami/xfa.rb +2863 -2882
- data/lib/origami/xreftable.rb +472 -384
- data/test/dataset/calc.pdf +85 -0
- data/test/dataset/crypto.pdf +82 -0
- data/test/dataset/empty.pdf +49 -0
- data/test/test_actions.rb +27 -0
- data/test/test_annotations.rb +90 -0
- data/test/test_pages.rb +31 -0
- data/test/test_pdf.rb +16 -0
- data/test/test_pdf_attachment.rb +34 -0
- data/test/test_pdf_create.rb +24 -0
- data/test/test_pdf_encrypt.rb +95 -0
- data/test/test_pdf_parse.rb +96 -0
- data/test/test_pdf_sign.rb +58 -0
- data/test/test_streams.rb +182 -0
- data/test/test_xrefs.rb +67 -0
- metadata +88 -58
- data/README +0 -67
- data/bin/pdf2graph +0 -121
- data/bin/pdfcocoon +0 -104
- data/lib/origami/file.rb +0 -233
- data/samples/README.txt +0 -45
- data/samples/actions/launch/calc.rb +0 -87
- data/samples/actions/launch/winparams.rb +0 -22
- data/samples/actions/loop/loopgoto.rb +0 -24
- data/samples/actions/loop/loopnamed.rb +0 -21
- data/samples/actions/named/named.rb +0 -31
- data/samples/actions/samba/smbrelay.rb +0 -26
- data/samples/actions/webbug/submitform.js +0 -26
- data/samples/actions/webbug/webbug-browser.rb +0 -68
- data/samples/actions/webbug/webbug-js.rb +0 -67
- data/samples/actions/webbug/webbug-reader.rb +0 -90
- data/samples/attachments/attach.rb +0 -40
- data/samples/attachments/attached.txt +0 -1
- data/samples/crypto/crypto.rb +0 -28
- data/samples/digsig/signed.rb +0 -46
- data/samples/exploits/cve-2008-2992-utilprintf.rb +0 -87
- data/samples/exploits/cve-2009-0927-geticon.rb +0 -65
- data/samples/exploits/exploit_customdictopen.rb +0 -55
- data/samples/exploits/getannots.rb +0 -69
- data/samples/flash/flash.rb +0 -31
- data/samples/javascript/attached.txt +0 -1
- data/samples/javascript/js.rb +0 -52
- data/templates/patterns.rb +0 -66
- data/templates/widgets.rb +0 -173
- data/templates/xdp.rb +0 -92
- data/test/ts_pdf.rb +0 -50
@@ -1,276 +1,262 @@
|
|
1
1
|
=begin
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
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/>.
|
3
|
+
This file is part of Origami, PDF manipulation framework for Ruby
|
4
|
+
Copyright (C) 2016 Guillaume Delugré.
|
5
|
+
|
6
|
+
Origami is free software: you can redistribute it and/or modify
|
7
|
+
it under the terms of the GNU Lesser General Public License as published by
|
8
|
+
the Free Software Foundation, either version 3 of the License, or
|
9
|
+
(at your option) any later version.
|
10
|
+
|
11
|
+
Origami is distributed in the hope that it will be useful,
|
12
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
GNU Lesser General Public License for more details.
|
15
|
+
|
16
|
+
You should have received a copy of the GNU Lesser General Public License
|
17
|
+
along with Origami. If not, see <http://www.gnu.org/licenses/>.
|
23
18
|
|
24
19
|
=end
|
25
20
|
|
26
21
|
module Origami
|
27
22
|
|
28
|
-
|
29
|
-
|
30
|
-
class PredictorError < Exception #:nodoc:
|
31
|
-
end
|
32
|
-
|
33
|
-
module Predictor
|
34
|
-
|
35
|
-
NONE = 1
|
36
|
-
TIFF = 2
|
37
|
-
PNG_NONE = 10
|
38
|
-
PNG_SUB = 11
|
39
|
-
PNG_UP = 12
|
40
|
-
PNG_AVERAGE = 13
|
41
|
-
PNG_PAETH = 14
|
42
|
-
PNG_OPTIMUM = 15
|
43
|
-
|
44
|
-
def self.do_pre_prediction(data, predictor = NONE, colors = 1, bpc = 8, columns = 1)
|
45
|
-
|
46
|
-
return data if predictor == NONE
|
47
|
-
|
48
|
-
unless (1..4) === colors.to_i
|
49
|
-
raise PredictorError, "Colors must be between 1 and 4"
|
50
|
-
end
|
23
|
+
module Filter
|
51
24
|
|
52
|
-
|
53
|
-
raise PredictorError, "BitsPerComponent must be in 1, 2, 4, 8 or 16"
|
25
|
+
class PredictorError < Error #:nodoc:
|
54
26
|
end
|
55
27
|
|
56
|
-
|
57
|
-
|
28
|
+
module Predictor
|
29
|
+
NONE = 1
|
30
|
+
TIFF = 2
|
31
|
+
PNG_NONE = 10
|
32
|
+
PNG_SUB = 11
|
33
|
+
PNG_UP = 12
|
34
|
+
PNG_AVERAGE = 13
|
35
|
+
PNG_PAETH = 14
|
36
|
+
PNG_OPTIMUM = 15
|
37
|
+
|
38
|
+
def self.do_pre_prediction(data, predictor: NONE, colors: 1, bpc: 8, columns: 1)
|
39
|
+
return data if predictor == NONE
|
40
|
+
|
41
|
+
unless (1..4) === colors.to_i
|
42
|
+
raise PredictorError.new("Colors must be between 1 and 4", input_data: data)
|
43
|
+
end
|
58
44
|
|
59
|
-
|
60
|
-
|
45
|
+
unless [1,2,4,8,16].include?(bpc.to_i)
|
46
|
+
raise PredictorError.new("BitsPerComponent must be in 1, 2, 4, 8 or 16", input_data: data)
|
47
|
+
end
|
61
48
|
|
62
|
-
|
63
|
-
|
49
|
+
# components per line
|
50
|
+
nvals = columns * colors
|
64
51
|
|
65
|
-
|
66
|
-
|
67
|
-
end
|
52
|
+
# bytes per pixel
|
53
|
+
bpp = (colors * bpc + 7) >> 3
|
68
54
|
|
69
|
-
|
70
|
-
|
71
|
-
elsif predictor >= 10 # PNG
|
72
|
-
do_png_pre_prediction(data, predictor, bpp, bpr)
|
73
|
-
else
|
74
|
-
raise PredictorError, "Unknown predictor : #{predictor}"
|
75
|
-
end
|
76
|
-
end
|
55
|
+
# bytes per row
|
56
|
+
bpr = (nvals * bpc + 7) >> 3
|
77
57
|
|
78
|
-
|
58
|
+
unless data.size % bpr == 0
|
59
|
+
raise PredictorError.new("Invalid data size #{data.size}, should be multiple of bpr=#{bpr}", input_data: data)
|
60
|
+
end
|
79
61
|
|
80
|
-
|
62
|
+
if predictor == TIFF
|
63
|
+
do_tiff_pre_prediction(data, colors, bpc, columns)
|
64
|
+
elsif predictor >= 10 # PNG
|
65
|
+
do_png_pre_prediction(data, predictor, bpp, bpr)
|
66
|
+
else
|
67
|
+
raise PredictorError.new("Unknown predictor : #{predictor}", input_data: data)
|
68
|
+
end
|
69
|
+
end
|
81
70
|
|
82
|
-
|
83
|
-
|
84
|
-
end
|
71
|
+
def self.do_post_prediction(data, predictor: NONE, colors: 1, bpc: 8, columns: 1)
|
72
|
+
return data if predictor == NONE
|
85
73
|
|
86
|
-
|
87
|
-
|
88
|
-
|
74
|
+
unless (1..4) === colors
|
75
|
+
raise PredictorError.new("Colors must be between 1 and 4", input_data: data)
|
76
|
+
end
|
89
77
|
|
90
|
-
|
91
|
-
|
78
|
+
unless [1,2,4,8,16].include?(bpc)
|
79
|
+
raise PredictorError.new("BitsPerComponent must be in 1, 2, 4, 8 or 16", input_data: data)
|
80
|
+
end
|
92
81
|
|
93
|
-
|
94
|
-
|
82
|
+
# components per line
|
83
|
+
nvals = columns * colors
|
95
84
|
|
96
|
-
|
97
|
-
|
85
|
+
# bytes per pixel
|
86
|
+
bpp = (colors * bpc + 7) >> 3
|
98
87
|
|
99
|
-
|
100
|
-
|
101
|
-
elsif predictor >= 10 # PNG
|
102
|
-
do_png_post_prediction(data, bpp, bpr)
|
103
|
-
else
|
104
|
-
raise PredictorError, "Unknown predictor : #{predictor}"
|
105
|
-
end
|
106
|
-
end
|
88
|
+
# bytes per row
|
89
|
+
bpr = ((nvals * bpc + 7) >> 3) + 1
|
107
90
|
|
108
|
-
|
91
|
+
if predictor == TIFF
|
92
|
+
do_tiff_post_prediction(data, colors, bpc, columns)
|
93
|
+
elsif predictor >= 10 # PNG
|
94
|
+
do_png_post_prediction(data, bpp, bpr)
|
95
|
+
else
|
96
|
+
raise PredictorError.new("Unknown predictor : #{predictor}", input_data: data)
|
97
|
+
end
|
98
|
+
end
|
109
99
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
100
|
+
def self.do_png_post_prediction(data, bpp, bpr)
|
101
|
+
result = ""
|
102
|
+
uprow = "\0" * bpr
|
103
|
+
thisrow = "\0" * bpr
|
104
|
+
nrows = (data.size + bpr - 1) / bpr
|
105
|
+
|
106
|
+
nrows.times do |irow|
|
107
|
+
line = data[irow * bpr, bpr]
|
108
|
+
predictor = 10 + line[0].ord
|
109
|
+
line[0] = "\0"
|
110
|
+
|
111
|
+
for i in (1..line.size-1)
|
112
|
+
up = uprow[i].ord
|
113
|
+
|
114
|
+
if bpp > i
|
115
|
+
left = upleft = 0
|
116
|
+
else
|
117
|
+
left = line[i-bpp].ord
|
118
|
+
upleft = uprow[i-bpp].ord
|
119
|
+
end
|
120
|
+
|
121
|
+
case predictor
|
122
|
+
when PNG_NONE
|
123
|
+
thisrow = line
|
124
|
+
when PNG_SUB
|
125
|
+
thisrow[i] = ((line[i].ord + left) & 0xFF).chr
|
126
|
+
when PNG_UP
|
127
|
+
thisrow[i] = ((line[i].ord + up) & 0xFF).chr
|
128
|
+
when PNG_AVERAGE
|
129
|
+
thisrow[i] = ((line[i].ord + ((left + up) / 2)) & 0xFF).chr
|
130
|
+
when PNG_PAETH
|
131
|
+
p = left + up - upleft
|
132
|
+
pa, pb, pc = (p - left).abs, (p - up).abs, (p - upleft).abs
|
133
|
+
|
134
|
+
thisrow[i] = ((line[i].ord +
|
135
|
+
case [ pa, pb, pc ].min
|
136
|
+
when pa then left
|
137
|
+
when pb then up
|
138
|
+
when pc then upleft
|
139
|
+
end
|
140
|
+
) & 0xFF).chr
|
141
|
+
else
|
142
|
+
unless Origami::OPTIONS[:ignore_png_errors]
|
143
|
+
raise PredictorError.new("Unknown PNG predictor : #{predictor}", input_data: data, decoded_data: result)
|
144
|
+
end
|
145
|
+
|
146
|
+
# behave as PNG_NONE
|
147
|
+
thisrow = line
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
result << thisrow[1..-1]
|
152
|
+
uprow = thisrow
|
153
|
+
end
|
116
154
|
|
117
|
-
|
118
|
-
|
119
|
-
line[0] = "\0"
|
155
|
+
result
|
156
|
+
end
|
120
157
|
|
121
|
-
|
122
|
-
|
158
|
+
def self.do_png_pre_prediction(data, predictor, bpp, bpr)
|
159
|
+
result = ""
|
160
|
+
nrows = data.size / bpr
|
161
|
+
|
162
|
+
line = "\0" + data[-bpr, bpr]
|
163
|
+
|
164
|
+
(nrows-1).downto(0) do |irow|
|
165
|
+
uprow =
|
166
|
+
if irow == 0
|
167
|
+
"\0" * (bpr+1)
|
168
|
+
else
|
169
|
+
"\0" + data[(irow-1)*bpr,bpr]
|
170
|
+
end
|
171
|
+
|
172
|
+
bpr.downto(1) do |i|
|
173
|
+
up = uprow[i].ord
|
174
|
+
left = line[i-bpp].ord
|
175
|
+
upleft = uprow[i-bpp].ord
|
176
|
+
|
177
|
+
case predictor
|
178
|
+
when PNG_SUB
|
179
|
+
line[i] = ((line[i].ord - left) & 0xFF).chr
|
180
|
+
when PNG_UP
|
181
|
+
line[i] = ((line[i].ord - up) & 0xFF).chr
|
182
|
+
when PNG_AVERAGE
|
183
|
+
line[i] = ((line[i].ord - ((left + up) / 2)) & 0xFF).chr
|
184
|
+
when PNG_PAETH
|
185
|
+
p = left + up - upleft
|
186
|
+
pa, pb, pc = (p - left).abs, (p - up).abs, (p - upleft).abs
|
187
|
+
|
188
|
+
line[i] = ((line[i].ord -
|
189
|
+
case [ pa, pb, pc ].min
|
190
|
+
when pa then left
|
191
|
+
when pb then up
|
192
|
+
when pc then upleft
|
193
|
+
end
|
194
|
+
) & 0xFF).chr
|
195
|
+
when PNG_NONE
|
196
|
+
else
|
197
|
+
raise PredictorError.new("Unsupported PNG predictor : #{predictor}", input_data: data)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
line[0] = (predictor - 10).chr
|
202
|
+
result = line + result
|
203
|
+
|
204
|
+
line = uprow
|
205
|
+
end
|
123
206
|
|
124
|
-
|
125
|
-
left = upleft = 0
|
126
|
-
else
|
127
|
-
left = line[i-bpp].ord
|
128
|
-
upleft = uprow[i-bpp].ord
|
207
|
+
result
|
129
208
|
end
|
130
209
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
when PNG_UP
|
137
|
-
thisrow[i] = ((line[i].ord + up) & 0xFF).chr
|
138
|
-
when PNG_AVERAGE
|
139
|
-
thisrow[i] = ((line[i].ord + ((left + up) / 2)) & 0xFF).chr
|
140
|
-
when PNG_PAETH
|
141
|
-
p = left + up - upleft
|
142
|
-
pa, pb, pc = (p - left).abs, (p - up).abs, (p - upleft).abs
|
143
|
-
|
144
|
-
thisrow[i] = ((line[i].ord +
|
145
|
-
case [ pa, pb, pc ].min
|
146
|
-
when pa then left
|
147
|
-
when pb then up
|
148
|
-
when pc then upleft
|
149
|
-
end
|
150
|
-
) & 0xFF).chr
|
151
|
-
else
|
152
|
-
puts "Unknown PNG predictor : #{predictor}"
|
153
|
-
thisrow = line
|
154
|
-
end
|
155
|
-
|
156
|
-
end
|
210
|
+
def self.do_tiff_post_prediction(data, colors, bpc, columns) #:nodoc:
|
211
|
+
bpr = (colors * bpc * columns + 7) >> 3
|
212
|
+
nrows = data.size / bpr
|
213
|
+
bitmask = (1 << bpc) - 1
|
214
|
+
result = Utils::BitWriter.new
|
157
215
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
(nrows-1).downto(0) do |irow|
|
173
|
-
|
174
|
-
uprow =
|
175
|
-
if irow == 0
|
176
|
-
"\0" * (bpr+1)
|
177
|
-
else
|
178
|
-
"\0" + data[(irow-1)*bpr,bpr]
|
179
|
-
end
|
180
|
-
|
181
|
-
bpr.downto(1) do |i|
|
182
|
-
|
183
|
-
up = uprow[i].ord
|
184
|
-
left = line[i-bpp].ord
|
185
|
-
upleft = uprow[i-bpp].ord
|
186
|
-
|
187
|
-
case predictor
|
188
|
-
when PNG_SUB
|
189
|
-
line[i] = ((line[i].ord - left) & 0xFF).chr
|
190
|
-
when PNG_UP
|
191
|
-
line[i] = ((line[i].ord - up) & 0xFF).chr
|
192
|
-
when PNG_AVERAGE
|
193
|
-
line[i] = ((line[i].ord - ((left + up) / 2)) & 0xFF).chr
|
194
|
-
when PNG_PAETH
|
195
|
-
p = left + up - upleft
|
196
|
-
pa, pb, pc = (p - left).abs, (p - up).abs, (p - upleft).abs
|
197
|
-
|
198
|
-
line[i] = ((line[i].ord -
|
199
|
-
case [ pa, pb, pc ].min
|
200
|
-
when pa then left
|
201
|
-
when pb then up
|
202
|
-
when pc then upleft
|
216
|
+
nrows.times do |irow|
|
217
|
+
line = Utils::BitReader.new(data[irow * bpr, bpr])
|
218
|
+
|
219
|
+
pixel = ::Array.new(colors, 0)
|
220
|
+
columns.times do
|
221
|
+
diffpixel = ::Array.new(colors) { line.read(bpc) }
|
222
|
+
pixel = pixel.zip(diffpixel).map!{|c, diff| (c + diff) & bitmask}
|
223
|
+
|
224
|
+
pixel.each do |c|
|
225
|
+
result.write(c, bpc)
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
result.final
|
203
230
|
end
|
204
|
-
|
205
|
-
|
206
|
-
else
|
207
|
-
raise PredictorError, "Unsupported PNG predictor : #{predictor}"
|
208
|
-
end
|
209
|
-
|
210
|
-
end
|
211
|
-
|
212
|
-
line[0] = (predictor - 10).chr
|
213
|
-
result = line + result
|
214
|
-
|
215
|
-
line = uprow
|
216
|
-
end
|
217
|
-
|
218
|
-
result
|
219
|
-
end
|
220
|
-
|
221
|
-
def self.do_tiff_post_prediction(data, colors, bpc, columns) #:nodoc:
|
222
|
-
|
223
|
-
bpr = (colors * bpc * columns + 7) >> 3
|
224
|
-
nrows = data.size / bpr
|
225
|
-
bitmask = (1 << bpc) - 1
|
226
|
-
result = Utils::BitWriter.new
|
227
|
-
|
228
|
-
nrows.times do |irow|
|
229
|
-
line = Utils::BitReader.new(data[irow * bpr, bpr])
|
230
|
-
|
231
|
-
pixel = ::Array.new(colors, 0)
|
232
|
-
columns.times do
|
233
|
-
diffpixel = ::Array.new(colors) { line.read(bpc) }
|
234
|
-
pixel = pixel.zip(diffpixel).map!{|c, diff| (c + diff) & bitmask}
|
235
|
-
|
236
|
-
pixel.each do |c|
|
237
|
-
result.write(c, bpc)
|
231
|
+
|
232
|
+
result.final.to_s
|
238
233
|
end
|
239
|
-
end
|
240
|
-
|
241
|
-
result.final
|
242
|
-
end
|
243
234
|
|
244
|
-
|
245
|
-
|
235
|
+
def self.do_tiff_pre_prediction(data, colors, bpc, columns) #:nodoc:
|
236
|
+
bpr = (colors * bpc * columns + 7) >> 3
|
237
|
+
nrows = data.size / bpr
|
238
|
+
bitmask = (1 << bpc) - 1
|
239
|
+
result = Utils::BitWriter.new
|
246
240
|
|
247
|
-
|
241
|
+
nrows.times do |irow|
|
242
|
+
line = Utils::BitReader.new(data[irow * bpr, bpr])
|
248
243
|
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
244
|
+
diffpixel = ::Array.new(colors, 0)
|
245
|
+
columns.times do
|
246
|
+
pixel = ::Array.new(colors) { line.read(bpc) }
|
247
|
+
diffpixel = diffpixel.zip(pixel).map!{|diff, c| (c - diff) & bitmask}
|
253
248
|
|
254
|
-
|
255
|
-
|
249
|
+
diffpixel.each do |c|
|
250
|
+
result.write(c, bpc)
|
251
|
+
end
|
252
|
+
end
|
256
253
|
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
diffpixel.each do |c|
|
263
|
-
result.write(c, bpc)
|
254
|
+
result.final
|
255
|
+
end
|
256
|
+
|
257
|
+
result.final.to_s
|
264
258
|
end
|
265
|
-
end
|
266
|
-
|
267
|
-
result.final
|
268
259
|
end
|
269
|
-
|
270
|
-
result.final.to_s
|
271
|
-
end
|
272
|
-
end
|
273
260
|
|
274
|
-
|
261
|
+
end
|
275
262
|
end
|
276
|
-
|