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.
Files changed (162) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +66 -0
  3. data/README.md +112 -0
  4. data/bin/config/pdfcop.conf.yml +232 -233
  5. data/bin/gui/about.rb +27 -37
  6. data/bin/gui/config.rb +108 -117
  7. data/bin/gui/file.rb +416 -365
  8. data/bin/gui/gtkhex.rb +1138 -1153
  9. data/bin/gui/hexview.rb +55 -57
  10. data/bin/gui/imgview.rb +48 -51
  11. data/bin/gui/menu.rb +388 -386
  12. data/bin/gui/properties.rb +114 -130
  13. data/bin/gui/signing.rb +571 -617
  14. data/bin/gui/textview.rb +77 -95
  15. data/bin/gui/treeview.rb +382 -387
  16. data/bin/gui/walker.rb +227 -232
  17. data/bin/gui/xrefs.rb +56 -60
  18. data/bin/pdf2pdfa +53 -57
  19. data/bin/pdf2ruby +212 -228
  20. data/bin/pdfcop +338 -348
  21. data/bin/pdfdecompress +58 -65
  22. data/bin/pdfdecrypt +56 -60
  23. data/bin/pdfencrypt +75 -80
  24. data/bin/pdfexplode +185 -182
  25. data/bin/pdfextract +201 -218
  26. data/bin/pdfmetadata +83 -82
  27. data/bin/pdfsh +4 -5
  28. data/bin/pdfwalker +1 -2
  29. data/bin/shell/.irbrc +45 -82
  30. data/bin/shell/console.rb +105 -130
  31. data/bin/shell/hexdump.rb +40 -64
  32. data/examples/README.md +34 -0
  33. data/examples/attachments/attachment.rb +38 -0
  34. data/examples/attachments/nested_document.rb +51 -0
  35. data/examples/encryption/encryption.rb +28 -0
  36. data/{samples/actions/triggerevents/trigger.rb → examples/events/events.rb} +13 -16
  37. data/examples/flash/flash.rb +37 -0
  38. data/{samples → examples}/flash/helloworld.swf +0 -0
  39. data/examples/forms/javascript.rb +54 -0
  40. data/examples/forms/xfa.rb +115 -0
  41. data/examples/javascript/hello_world.rb +22 -0
  42. data/examples/javascript/js_emulation.rb +54 -0
  43. data/examples/loop/goto.rb +32 -0
  44. data/examples/loop/named.rb +33 -0
  45. data/examples/signature/signature.rb +65 -0
  46. data/examples/uri/javascript.rb +56 -0
  47. data/examples/uri/open-uri.rb +21 -0
  48. data/examples/uri/submitform.rb +47 -0
  49. data/lib/origami.rb +29 -42
  50. data/lib/origami/3d.rb +350 -225
  51. data/lib/origami/acroform.rb +262 -288
  52. data/lib/origami/actions.rb +268 -288
  53. data/lib/origami/annotations.rb +697 -722
  54. data/lib/origami/array.rb +258 -184
  55. data/lib/origami/boolean.rb +74 -84
  56. data/lib/origami/catalog.rb +397 -434
  57. data/lib/origami/collections.rb +144 -0
  58. data/lib/origami/destinations.rb +233 -194
  59. data/lib/origami/dictionary.rb +253 -232
  60. data/lib/origami/encryption.rb +1274 -1243
  61. data/lib/origami/export.rb +232 -268
  62. data/lib/origami/extensions/fdf.rb +307 -220
  63. data/lib/origami/extensions/ppklite.rb +368 -435
  64. data/lib/origami/filespec.rb +197 -0
  65. data/lib/origami/filters.rb +301 -295
  66. data/lib/origami/filters/ascii.rb +177 -180
  67. data/lib/origami/filters/ccitt.rb +528 -535
  68. data/lib/origami/filters/crypt.rb +26 -35
  69. data/lib/origami/filters/dct.rb +46 -52
  70. data/lib/origami/filters/flate.rb +95 -94
  71. data/lib/origami/filters/jbig2.rb +49 -55
  72. data/lib/origami/filters/jpx.rb +38 -44
  73. data/lib/origami/filters/lzw.rb +189 -183
  74. data/lib/origami/filters/predictors.rb +221 -235
  75. data/lib/origami/filters/runlength.rb +103 -104
  76. data/lib/origami/font.rb +173 -186
  77. data/lib/origami/functions.rb +67 -81
  78. data/lib/origami/graphics.rb +25 -21
  79. data/lib/origami/graphics/colors.rb +178 -187
  80. data/lib/origami/graphics/instruction.rb +79 -85
  81. data/lib/origami/graphics/path.rb +142 -148
  82. data/lib/origami/graphics/patterns.rb +160 -167
  83. data/lib/origami/graphics/render.rb +43 -50
  84. data/lib/origami/graphics/state.rb +138 -153
  85. data/lib/origami/graphics/text.rb +188 -205
  86. data/lib/origami/graphics/xobject.rb +819 -815
  87. data/lib/origami/header.rb +63 -78
  88. data/lib/origami/javascript.rb +596 -597
  89. data/lib/origami/linearization.rb +285 -290
  90. data/lib/origami/metadata.rb +139 -148
  91. data/lib/origami/name.rb +112 -148
  92. data/lib/origami/null.rb +53 -62
  93. data/lib/origami/numeric.rb +162 -175
  94. data/lib/origami/obfuscation.rb +186 -174
  95. data/lib/origami/object.rb +593 -573
  96. data/lib/origami/outline.rb +42 -47
  97. data/lib/origami/outputintents.rb +73 -82
  98. data/lib/origami/page.rb +703 -592
  99. data/lib/origami/parser.rb +238 -290
  100. data/lib/origami/parsers/fdf.rb +41 -33
  101. data/lib/origami/parsers/pdf.rb +75 -95
  102. data/lib/origami/parsers/pdf/lazy.rb +137 -0
  103. data/lib/origami/parsers/pdf/linear.rb +64 -66
  104. data/lib/origami/parsers/ppklite.rb +34 -70
  105. data/lib/origami/pdf.rb +1030 -1005
  106. data/lib/origami/reference.rb +102 -102
  107. data/lib/origami/signature.rb +591 -609
  108. data/lib/origami/stream.rb +668 -551
  109. data/lib/origami/string.rb +397 -373
  110. data/lib/origami/template/patterns.rb +56 -0
  111. data/lib/origami/template/widgets.rb +151 -0
  112. data/lib/origami/trailer.rb +144 -158
  113. data/lib/origami/tree.rb +62 -0
  114. data/lib/origami/version.rb +23 -0
  115. data/lib/origami/webcapture.rb +88 -79
  116. data/lib/origami/xfa.rb +2863 -2882
  117. data/lib/origami/xreftable.rb +472 -384
  118. data/test/dataset/calc.pdf +85 -0
  119. data/test/dataset/crypto.pdf +82 -0
  120. data/test/dataset/empty.pdf +49 -0
  121. data/test/test_actions.rb +27 -0
  122. data/test/test_annotations.rb +90 -0
  123. data/test/test_pages.rb +31 -0
  124. data/test/test_pdf.rb +16 -0
  125. data/test/test_pdf_attachment.rb +34 -0
  126. data/test/test_pdf_create.rb +24 -0
  127. data/test/test_pdf_encrypt.rb +95 -0
  128. data/test/test_pdf_parse.rb +96 -0
  129. data/test/test_pdf_sign.rb +58 -0
  130. data/test/test_streams.rb +182 -0
  131. data/test/test_xrefs.rb +67 -0
  132. metadata +88 -58
  133. data/README +0 -67
  134. data/bin/pdf2graph +0 -121
  135. data/bin/pdfcocoon +0 -104
  136. data/lib/origami/file.rb +0 -233
  137. data/samples/README.txt +0 -45
  138. data/samples/actions/launch/calc.rb +0 -87
  139. data/samples/actions/launch/winparams.rb +0 -22
  140. data/samples/actions/loop/loopgoto.rb +0 -24
  141. data/samples/actions/loop/loopnamed.rb +0 -21
  142. data/samples/actions/named/named.rb +0 -31
  143. data/samples/actions/samba/smbrelay.rb +0 -26
  144. data/samples/actions/webbug/submitform.js +0 -26
  145. data/samples/actions/webbug/webbug-browser.rb +0 -68
  146. data/samples/actions/webbug/webbug-js.rb +0 -67
  147. data/samples/actions/webbug/webbug-reader.rb +0 -90
  148. data/samples/attachments/attach.rb +0 -40
  149. data/samples/attachments/attached.txt +0 -1
  150. data/samples/crypto/crypto.rb +0 -28
  151. data/samples/digsig/signed.rb +0 -46
  152. data/samples/exploits/cve-2008-2992-utilprintf.rb +0 -87
  153. data/samples/exploits/cve-2009-0927-geticon.rb +0 -65
  154. data/samples/exploits/exploit_customdictopen.rb +0 -55
  155. data/samples/exploits/getannots.rb +0 -69
  156. data/samples/flash/flash.rb +0 -31
  157. data/samples/javascript/attached.txt +0 -1
  158. data/samples/javascript/js.rb +0 -52
  159. data/templates/patterns.rb +0 -66
  160. data/templates/widgets.rb +0 -173
  161. data/templates/xdp.rb +0 -92
  162. data/test/ts_pdf.rb +0 -50
@@ -1,276 +1,262 @@
1
1
  =begin
2
2
 
3
- = File
4
- filters/predictors.rb
5
-
6
- = Info
7
- This file is part of Origami, PDF manipulation framework for Ruby
8
- Copyright (C) 2010 Guillaume Delugré <guillaume AT security-labs DOT 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/>.
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
- module Filter
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
- unless [1,2,4,8,16].include?(bpc.to_i)
53
- raise PredictorError, "BitsPerComponent must be in 1, 2, 4, 8 or 16"
25
+ class PredictorError < Error #:nodoc:
54
26
  end
55
27
 
56
- # components per line
57
- nvals = columns * colors
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
- # bytes per pixel
60
- bpp = (colors * bpc + 7) >> 3
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
- # bytes per row
63
- bpr = (nvals * bpc + 7) >> 3
49
+ # components per line
50
+ nvals = columns * colors
64
51
 
65
- unless data.size % bpr == 0
66
- raise PredictorError, "Invalid data size #{data.size}, should be multiple of bpr=#{bpr}"
67
- end
52
+ # bytes per pixel
53
+ bpp = (colors * bpc + 7) >> 3
68
54
 
69
- if predictor == TIFF
70
- do_tiff_pre_prediction(data, colors, bpc, columns)
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
- def self.do_post_prediction(data, predictor = NONE, colors = 1, bpc = 8, columns = 1)
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
- return data if predictor == NONE
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
- unless (1..4) === colors
83
- raise PredictorError, "Colors must be between 1 and 4"
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
- unless [1,2,4,8,16].include?(bpc)
87
- raise PredictorError, "BitsPerComponent must be in 1, 2, 4, 8 or 16"
88
- end
74
+ unless (1..4) === colors
75
+ raise PredictorError.new("Colors must be between 1 and 4", input_data: data)
76
+ end
89
77
 
90
- # components per line
91
- nvals = columns * colors
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
- # bytes per pixel
94
- bpp = (colors * bpc + 7) >> 3
82
+ # components per line
83
+ nvals = columns * colors
95
84
 
96
- # bytes per row
97
- bpr = ((nvals * bpc + 7) >> 3) + 1
85
+ # bytes per pixel
86
+ bpp = (colors * bpc + 7) >> 3
98
87
 
99
- if predictor == TIFF
100
- do_tiff_post_prediction(data, colors, bpc, columns)
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
- def self.do_png_post_prediction(data, bpp, bpr)
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
- result = ""
111
- uprow = "\0" * bpr
112
- thisrow = "\0" * bpr
113
- nrows = (data.size + bpr - 1) / bpr
114
-
115
- nrows.times do |irow|
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
- line = data[irow * bpr, bpr]
118
- predictor = 10 + line[0].ord
119
- line[0] = "\0"
155
+ result
156
+ end
120
157
 
121
- for i in (1..line.size-1)
122
- up = uprow[i].ord
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
- if bpp > i
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
- case predictor
132
- when PNG_NONE
133
- thisrow = line
134
- when PNG_SUB
135
- thisrow[i] = ((line[i].ord + left) & 0xFF).chr
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
- result << thisrow[1..-1]
159
- uprow = thisrow
160
- end
161
-
162
- result
163
- end
164
-
165
- def self.do_png_pre_prediction(data, predictor, bpp, bpr)
166
-
167
- result = ""
168
- nrows = data.size / bpr
169
-
170
- line = "\0" + data[-bpr, bpr]
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
- ) & 0xFF).chr
205
- when PNG_NONE
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
- result.final.to_s
245
- end
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
- def self.do_tiff_pre_prediction(data, colors, bpc, columns) #:nodoc:
241
+ nrows.times do |irow|
242
+ line = Utils::BitReader.new(data[irow * bpr, bpr])
248
243
 
249
- bpr = (colors * bpc * columns + 7) >> 3
250
- nrows = data.size / bpr
251
- bitmask = (1 << bpc) - 1
252
- result = Utils::BitWriter.new
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
- nrows.times do |irow|
255
- line = Utils::BitReader.new(data[irow * bpr, bpr])
249
+ diffpixel.each do |c|
250
+ result.write(c, bpc)
251
+ end
252
+ end
256
253
 
257
- diffpixel = ::Array.new(colors, 0)
258
- columns.times do
259
- pixel = ::Array.new(colors) { line.read(bpc) }
260
- diffpixel = diffpixel.zip(pixel).map!{|diff, c| (c - diff) & bitmask}
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
- end
261
+ end
275
262
  end
276
-