origami-docspring 2.2.0 → 2.3.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 (118) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +18 -0
  3. data/examples/attachments/attachment.rb +7 -8
  4. data/examples/attachments/nested_document.rb +6 -5
  5. data/examples/encryption/encryption.rb +5 -4
  6. data/examples/events/events.rb +7 -6
  7. data/examples/flash/flash.rb +10 -9
  8. data/examples/forms/javascript.rb +14 -13
  9. data/examples/forms/xfa.rb +67 -66
  10. data/examples/javascript/hello_world.rb +6 -5
  11. data/examples/javascript/js_emulation.rb +26 -26
  12. data/examples/loop/goto.rb +12 -11
  13. data/examples/loop/named.rb +17 -16
  14. data/examples/signature/signature.rb +11 -11
  15. data/examples/uri/javascript.rb +25 -24
  16. data/examples/uri/open-uri.rb +5 -4
  17. data/examples/uri/submitform.rb +11 -10
  18. data/lib/origami/3d.rb +330 -334
  19. data/lib/origami/acroform.rb +267 -268
  20. data/lib/origami/actions.rb +266 -278
  21. data/lib/origami/annotations.rb +659 -670
  22. data/lib/origami/array.rb +192 -196
  23. data/lib/origami/boolean.rb +66 -70
  24. data/lib/origami/catalog.rb +360 -363
  25. data/lib/origami/collections.rb +132 -133
  26. data/lib/origami/compound.rb +125 -129
  27. data/lib/origami/destinations.rb +226 -237
  28. data/lib/origami/dictionary.rb +155 -154
  29. data/lib/origami/encryption.rb +967 -923
  30. data/lib/origami/extensions/fdf.rb +270 -275
  31. data/lib/origami/extensions/ppklite.rb +323 -328
  32. data/lib/origami/filespec.rb +170 -173
  33. data/lib/origami/filters/ascii.rb +162 -167
  34. data/lib/origami/filters/ccitt/tables.rb +248 -252
  35. data/lib/origami/filters/ccitt.rb +309 -312
  36. data/lib/origami/filters/crypt.rb +31 -34
  37. data/lib/origami/filters/dct.rb +47 -50
  38. data/lib/origami/filters/flate.rb +57 -60
  39. data/lib/origami/filters/jbig2.rb +50 -53
  40. data/lib/origami/filters/jpx.rb +40 -43
  41. data/lib/origami/filters/lzw.rb +151 -155
  42. data/lib/origami/filters/predictors.rb +250 -255
  43. data/lib/origami/filters/runlength.rb +111 -115
  44. data/lib/origami/filters.rb +319 -325
  45. data/lib/origami/font.rb +173 -177
  46. data/lib/origami/functions.rb +62 -66
  47. data/lib/origami/graphics/colors.rb +203 -208
  48. data/lib/origami/graphics/instruction.rb +79 -81
  49. data/lib/origami/graphics/path.rb +141 -144
  50. data/lib/origami/graphics/patterns.rb +156 -160
  51. data/lib/origami/graphics/render.rb +51 -47
  52. data/lib/origami/graphics/state.rb +144 -142
  53. data/lib/origami/graphics/text.rb +185 -188
  54. data/lib/origami/graphics/xobject.rb +818 -804
  55. data/lib/origami/graphics.rb +25 -26
  56. data/lib/origami/header.rb +63 -65
  57. data/lib/origami/javascript.rb +718 -651
  58. data/lib/origami/linearization.rb +284 -285
  59. data/lib/origami/metadata.rb +156 -135
  60. data/lib/origami/name.rb +98 -100
  61. data/lib/origami/null.rb +49 -51
  62. data/lib/origami/numeric.rb +133 -135
  63. data/lib/origami/obfuscation.rb +180 -182
  64. data/lib/origami/object.rb +634 -631
  65. data/lib/origami/optionalcontent.rb +147 -149
  66. data/lib/origami/outline.rb +46 -48
  67. data/lib/origami/outputintents.rb +76 -77
  68. data/lib/origami/page.rb +637 -596
  69. data/lib/origami/parser.rb +214 -221
  70. data/lib/origami/parsers/fdf.rb +44 -45
  71. data/lib/origami/parsers/pdf/lazy.rb +147 -154
  72. data/lib/origami/parsers/pdf/linear.rb +104 -109
  73. data/lib/origami/parsers/pdf.rb +109 -107
  74. data/lib/origami/parsers/ppklite.rb +44 -46
  75. data/lib/origami/pdf.rb +886 -896
  76. data/lib/origami/reference.rb +116 -120
  77. data/lib/origami/signature.rb +617 -625
  78. data/lib/origami/stream.rb +560 -558
  79. data/lib/origami/string.rb +366 -368
  80. data/lib/origami/template/patterns.rb +50 -52
  81. data/lib/origami/template/widgets.rb +111 -114
  82. data/lib/origami/trailer.rb +153 -157
  83. data/lib/origami/tree.rb +55 -57
  84. data/lib/origami/version.rb +19 -19
  85. data/lib/origami/webcapture.rb +87 -90
  86. data/lib/origami/xfa/config.rb +409 -414
  87. data/lib/origami/xfa/connectionset.rb +113 -117
  88. data/lib/origami/xfa/datasets.rb +38 -42
  89. data/lib/origami/xfa/localeset.rb +33 -37
  90. data/lib/origami/xfa/package.rb +49 -52
  91. data/lib/origami/xfa/pdf.rb +54 -59
  92. data/lib/origami/xfa/signature.rb +33 -37
  93. data/lib/origami/xfa/sourceset.rb +34 -38
  94. data/lib/origami/xfa/stylesheet.rb +35 -39
  95. data/lib/origami/xfa/template.rb +1630 -1634
  96. data/lib/origami/xfa/xdc.rb +33 -37
  97. data/lib/origami/xfa/xfa.rb +132 -123
  98. data/lib/origami/xfa/xfdf.rb +34 -38
  99. data/lib/origami/xfa/xmpmeta.rb +34 -38
  100. data/lib/origami/xfa.rb +50 -53
  101. data/lib/origami/xreftable.rb +462 -462
  102. data/lib/origami.rb +37 -38
  103. data/test/test_actions.rb +22 -20
  104. data/test/test_annotations.rb +54 -52
  105. data/test/test_forms.rb +23 -21
  106. data/test/test_native_types.rb +82 -78
  107. data/test/test_object_tree.rb +25 -24
  108. data/test/test_pages.rb +43 -41
  109. data/test/test_pdf.rb +2 -0
  110. data/test/test_pdf_attachment.rb +23 -21
  111. data/test/test_pdf_create.rb +16 -15
  112. data/test/test_pdf_encrypt.rb +69 -66
  113. data/test/test_pdf_parse.rb +131 -129
  114. data/test/test_pdf_parse_lazy.rb +53 -53
  115. data/test/test_pdf_sign.rb +67 -67
  116. data/test/test_streams.rb +145 -143
  117. data/test/test_xrefs.rb +46 -45
  118. metadata +64 -8
@@ -1,292 +1,287 @@
1
- =begin
2
-
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/>.
18
-
19
- =end
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # This file is part of Origami, PDF manipulation framework for Ruby
5
+ # Copyright (C) 2016 Guillaume Delugré.
6
+ #
7
+ # Origami is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Lesser General Public License as published by
9
+ # the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # Origami is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Lesser General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Lesser General Public License
18
+ # along with Origami. If not, see <http://www.gnu.org/licenses/>.
19
+ #
20
20
 
21
21
  module Origami
22
+ module Filter
23
+ class PredictorError < Error # :nodoc:
24
+ end
22
25
 
23
- module Filter
24
-
25
- class PredictorError < Error #:nodoc:
26
+ module Predictor
27
+ NONE = 1
28
+ TIFF = 2
29
+ PNG_NONE = 10
30
+ PNG_SUB = 11
31
+ PNG_UP = 12
32
+ PNG_AVERAGE = 13
33
+ PNG_PAETH = 14
34
+ PNG_OPTIMUM = 15
35
+
36
+ class DecodeParms < Dictionary
37
+ include StandardObject
38
+
39
+ field :Predictor, Type: Integer, Default: 1
40
+ field :Colors, Type: Integer, Default: 1
41
+ field :BitsPerComponent, Type: Integer, Default: 8
42
+ field :Columns, Type: Integer, Default: 1
43
+ end
44
+
45
+ def self.included(receiver)
46
+ raise TypeError, "Predictors only applies to Filters" unless receiver.include?(Filter)
47
+ end
48
+
49
+ #
50
+ # Create a new predictive Filter.
51
+ # _parameters_:: A hash of filter options.
52
+ #
53
+ def initialize(parameters = {})
54
+ super(DecodeParms.new(parameters))
55
+ end
56
+
57
+ private
58
+
59
+ def pre_prediction(data)
60
+ return data unless @params.Predictor.is_a?(Integer)
61
+
62
+ apply_pre_prediction(data, **prediction_parameters)
63
+ end
64
+
65
+ def post_prediction(data)
66
+ return data unless @params.Predictor.is_a?(Integer)
67
+
68
+ apply_post_prediction(data, **prediction_parameters)
69
+ end
70
+
71
+ def prediction_parameters
72
+ {
73
+ predictor: @params.Predictor.to_i,
74
+ colors: @params.Colors.is_a?(Integer) ? @params.Colors.to_i : 1,
75
+ bpc: @params.BitsPerComponent.is_a?(Integer) ? @params.BitsPerComponent.to_i : 8,
76
+ columns: @params.Columns.is_a?(Integer) ? @params.Columns.to_i : 1,
77
+ }
78
+ end
79
+
80
+ def apply_pre_prediction(data, predictor: NONE, colors: 1, bpc: 8, columns: 1)
81
+ return data if data.empty? || (predictor == NONE)
82
+
83
+ bpp, bpr = compute_bpp_bpr(data, columns, colors, bpc)
84
+
85
+ unless data.size % bpr == 0
86
+ raise PredictorError.new("Invalid data size #{data.size}, should be multiple of bpr=#{bpr}",
87
+ input_data: data)
26
88
  end
27
89
 
28
- module Predictor
29
-
30
- NONE = 1
31
- TIFF = 2
32
- PNG_NONE = 10
33
- PNG_SUB = 11
34
- PNG_UP = 12
35
- PNG_AVERAGE = 13
36
- PNG_PAETH = 14
37
- PNG_OPTIMUM = 15
38
-
39
- class DecodeParms < Dictionary
40
- include StandardObject
41
-
42
- field :Predictor, :Type => Integer, :Default => 1
43
- field :Colors, :Type => Integer, :Default => 1
44
- field :BitsPerComponent, :Type => Integer, :Default => 8
45
- field :Columns, :Type => Integer, :Default => 1
46
- end
47
-
48
- def self.included(receiver)
49
- raise TypeError, "Predictors only applies to Filters" unless receiver.include?(Filter)
50
- end
51
-
52
- #
53
- # Create a new predictive Filter.
54
- # _parameters_:: A hash of filter options.
55
- #
56
- def initialize(parameters = {})
57
- super(DecodeParms.new(parameters))
58
- end
59
-
60
- private
61
-
62
- def pre_prediction(data)
63
- return data unless @params.Predictor.is_a?(Integer)
64
-
65
- apply_pre_prediction(data, **prediction_parameters)
66
- end
90
+ if predictor == TIFF
91
+ tiff_pre_prediction(data, colors, bpc, columns)
92
+ elsif predictor >= 10 # PNG
93
+ png_pre_prediction(data, predictor, bpp, bpr)
94
+ else
95
+ raise PredictorError.new("Unknown predictor : #{predictor}", input_data: data)
96
+ end
97
+ end
67
98
 
68
- def post_prediction(data)
69
- return data unless @params.Predictor.is_a?(Integer)
99
+ def apply_post_prediction(data, predictor: NONE, colors: 1, bpc: 8, columns: 1)
100
+ return data if data.empty? || (predictor == NONE)
70
101
 
71
- apply_post_prediction(data, **prediction_parameters)
72
- end
73
-
74
- def prediction_parameters
75
- {
76
- predictor: @params.Predictor.to_i,
77
- colors: @params.Colors.is_a?(Integer) ? @params.Colors.to_i : 1,
78
- bpc: @params.BitsPerComponent.is_a?(Integer) ? @params.BitsPerComponent.to_i : 8,
79
- columns: @params.Columns.is_a?(Integer) ? @params.Columns.to_i : 1,
80
- }
81
- end
102
+ bpp, bpr = compute_bpp_bpr(data, columns, colors, bpc)
82
103
 
83
- def apply_pre_prediction(data, predictor: NONE, colors: 1, bpc: 8, columns: 1)
84
- return data if data.empty? or predictor == NONE
85
-
86
- bpp, bpr = compute_bpp_bpr(data, columns, colors, bpc)
104
+ if predictor == TIFF
105
+ tiff_post_prediction(data, colors, bpc, columns)
106
+ elsif predictor >= 10 # PNG
107
+ # Each line has an extra predictor byte.
108
+ png_post_prediction(data, bpp, bpr + 1)
109
+ else
110
+ raise PredictorError.new("Unknown predictor : #{predictor}", input_data: data)
111
+ end
112
+ end
113
+
114
+ #
115
+ # Computes the number of bytes per pixel and number of bytes per row.
116
+ #
117
+ def compute_bpp_bpr(data, columns, colors, bpc)
118
+ unless colors.between?(1, 4)
119
+ raise PredictorError.new("Colors must be between 1 and 4", input_data: data)
120
+ end
87
121
 
88
- unless data.size % bpr == 0
89
- raise PredictorError.new("Invalid data size #{data.size}, should be multiple of bpr=#{bpr}",
90
- input_data: data)
91
- end
122
+ unless [1, 2, 4, 8, 16].include?(bpc)
123
+ raise PredictorError.new("BitsPerComponent must be in 1, 2, 4, 8 or 16", input_data: data)
124
+ end
92
125
 
93
- if predictor == TIFF
94
- tiff_pre_prediction(data, colors, bpc, columns)
95
- elsif predictor >= 10 # PNG
96
- png_pre_prediction(data, predictor, bpp, bpr)
97
- else
98
- raise PredictorError.new("Unknown predictor : #{predictor}", input_data: data)
99
- end
126
+ # components per line
127
+ nvals = columns * colors
128
+
129
+ # bytes per pixel
130
+ bpp = (colors * bpc + 7) >> 3
131
+
132
+ # bytes per row
133
+ bpr = (nvals * bpc + 7) >> 3
134
+
135
+ [bpp, bpr]
136
+ end
137
+
138
+ #
139
+ # Decodes the PNG input data.
140
+ # Each line should be prepended by a byte identifying a PNG predictor.
141
+ #
142
+ def png_post_prediction(data, bpp, bpr)
143
+ result = +""
144
+ uprow = +"\0" * bpr
145
+ thisrow = +"\0" * bpr
146
+ nrows = (data.size + bpr - 1) / bpr
147
+
148
+ nrows.times do |irow|
149
+ line = data[irow * bpr, bpr]
150
+ predictor = 10 + line[0].ord
151
+ line[0] = "\0"
152
+
153
+ (1..line.size - 1).each do |i|
154
+ up = uprow[i].ord
155
+
156
+ if bpp > i
157
+ left = upleft = 0
158
+ else
159
+ left = line[i - bpp].ord
160
+ upleft = uprow[i - bpp].ord
100
161
  end
101
162
 
102
- def apply_post_prediction(data, predictor: NONE, colors: 1, bpc: 8, columns: 1)
103
- return data if data.empty? or predictor == NONE
104
-
105
- bpp, bpr = compute_bpp_bpr(data, columns, colors, bpc)
163
+ begin
164
+ thisrow[i] = png_apply_prediction(predictor, line[i].ord, up, left, upleft, &:+)
165
+ rescue PredictorError => error
166
+ thisrow[i] = line[i] if Origami::OPTIONS[:ignore_png_errors]
106
167
 
107
- if predictor == TIFF
108
- tiff_post_prediction(data, colors, bpc, columns)
109
- elsif predictor >= 10 # PNG
110
- # Each line has an extra predictor byte.
111
- png_post_prediction(data, bpp, bpr + 1)
112
- else
113
- raise PredictorError.new("Unknown predictor : #{predictor}", input_data: data)
114
- end
168
+ error.input_data = data
169
+ error.decoded_data = result
170
+ raise(error)
115
171
  end
172
+ end
116
173
 
117
- #
118
- # Computes the number of bytes per pixel and number of bytes per row.
119
- #
120
- def compute_bpp_bpr(data, columns, colors, bpc)
121
- unless colors.between?(1, 4)
122
- raise PredictorError.new("Colors must be between 1 and 4", input_data: data)
123
- end
124
-
125
- unless [1,2,4,8,16].include?(bpc)
126
- raise PredictorError.new("BitsPerComponent must be in 1, 2, 4, 8 or 16", input_data: data)
127
- end
128
-
129
- # components per line
130
- nvals = columns * colors
174
+ result << thisrow[1..]
175
+ uprow = thisrow
176
+ end
131
177
 
132
- # bytes per pixel
133
- bpp = (colors * bpc + 7) >> 3
178
+ result
179
+ end
134
180
 
135
- # bytes per row
136
- bpr = (nvals * bpc + 7) >> 3
181
+ #
182
+ # Encodes the input data given a PNG predictor.
183
+ #
184
+ def png_pre_prediction(data, predictor, bpp, bpr)
185
+ result = ""
186
+ nrows = data.size / bpr
137
187
 
138
- [ bpp, bpr ]
139
- end
188
+ line = "\0" + data[-bpr, bpr]
140
189
 
141
- #
142
- # Decodes the PNG input data.
143
- # Each line should be prepended by a byte identifying a PNG predictor.
144
- #
145
- def png_post_prediction(data, bpp, bpr)
146
- result = ""
147
- uprow = "\0" * bpr
148
- thisrow = "\0" * bpr
149
- nrows = (data.size + bpr - 1) / bpr
150
-
151
- nrows.times do |irow|
152
- line = data[irow * bpr, bpr]
153
- predictor = 10 + line[0].ord
154
- line[0] = "\0"
155
-
156
- for i in (1..line.size-1)
157
- up = uprow[i].ord
158
-
159
- if bpp > i
160
- left = upleft = 0
161
- else
162
- left = line[i - bpp].ord
163
- upleft = uprow[i - bpp].ord
164
- end
165
-
166
- begin
167
- thisrow[i] = png_apply_prediction(predictor, line[i].ord, up, left, upleft, &:+)
168
- rescue PredictorError => error
169
- thisrow[i] = line[i] if Origami::OPTIONS[:ignore_png_errors]
170
-
171
- error.input_data = data
172
- error.decoded_data = result
173
- raise(error)
174
- end
175
- end
176
-
177
- result << thisrow[1..-1]
178
- uprow = thisrow
179
- end
180
-
181
- result
190
+ (nrows - 1).downto(0) do |irow|
191
+ uprow =
192
+ if irow == 0
193
+ "\0" * (bpr + 1)
194
+ else
195
+ "\0" + data[(irow - 1) * bpr, bpr]
182
196
  end
183
197
 
184
- #
185
- # Encodes the input data given a PNG predictor.
186
- #
187
- def png_pre_prediction(data, predictor, bpp, bpr)
188
- result = ""
189
- nrows = data.size / bpr
198
+ bpr.downto(1) do |i|
199
+ up = uprow[i].ord
200
+ left = line[i - bpp].ord
201
+ upleft = uprow[i - bpp].ord
190
202
 
191
- line = "\0" + data[-bpr, bpr]
203
+ line[i] = png_apply_prediction(predictor, line[i].ord, up, left, upleft, &:-)
204
+ end
192
205
 
193
- (nrows - 1).downto(0) do |irow|
194
- uprow =
195
- if irow == 0
196
- "\0" * (bpr + 1)
197
- else
198
- "\0" + data[(irow - 1) * bpr, bpr]
199
- end
206
+ line[0] = (predictor - 10).chr
207
+ result = line + result
200
208
 
201
- bpr.downto(1) do |i|
202
- up = uprow[i].ord
203
- left = line[i - bpp].ord
204
- upleft = uprow[i - bpp].ord
205
-
206
- line[i] = png_apply_prediction(predictor, line[i].ord, up, left, upleft, &:-)
207
- end
209
+ line = uprow
210
+ end
208
211
 
209
- line[0] = (predictor - 10).chr
210
- result = line + result
212
+ result
213
+ end
214
+
215
+ #
216
+ # Computes the next component value given a predictor and adjacent components.
217
+ # A block must be passed to apply the operation.
218
+ #
219
+ def png_apply_prediction(predictor, value, up, left, upleft)
220
+ result =
221
+ case predictor
222
+ when PNG_NONE
223
+ value
224
+ when PNG_SUB
225
+ yield(value, left)
226
+ when PNG_UP
227
+ yield(value, up)
228
+ when PNG_AVERAGE
229
+ yield(value, (left + up) / 2)
230
+ when PNG_PAETH
231
+ yield(value, png_paeth_choose(up, left, upleft))
232
+ else
233
+ raise PredictorError, "Unsupported PNG predictor : #{predictor}"
234
+ end
235
+
236
+ (result & 0xFF).chr
237
+ end
238
+
239
+ #
240
+ # Choose the preferred value in a PNG paeth predictor given the left, up and up left samples.
241
+ #
242
+ def png_paeth_choose(left, up, upleft)
243
+ p = left + up - upleft
244
+ pa, pb, pc = (p - left).abs, (p - up).abs, (p - upleft).abs
245
+
246
+ case [pa, pb, pc].min
247
+ when pa then left
248
+ when pb then up
249
+ when pc then upleft
250
+ end
251
+ end
211
252
 
212
- line = uprow
213
- end
253
+ def tiff_post_prediction(data, colors, bpc, columns) # :nodoc:
254
+ tiff_apply_prediction(data, colors, bpc, columns, &:+)
255
+ end
214
256
 
215
- result
216
- end
257
+ def tiff_pre_prediction(data, colors, bpc, columns) # :nodoc:
258
+ tiff_apply_prediction(data, colors, bpc, columns, &:-)
259
+ end
217
260
 
218
- #
219
- # Computes the next component value given a predictor and adjacent components.
220
- # A block must be passed to apply the operation.
221
- #
222
- def png_apply_prediction(predictor, value, up, left, upleft)
223
-
224
- result =
225
- case predictor
226
- when PNG_NONE
227
- value
228
- when PNG_SUB
229
- yield(value, left)
230
- when PNG_UP
231
- yield(value, up)
232
- when PNG_AVERAGE
233
- yield(value, (left + up) / 2)
234
- when PNG_PAETH
235
- yield(value, png_paeth_choose(up, left, upleft))
236
- else
237
- raise PredictorError, "Unsupported PNG predictor : #{predictor}"
238
- end
239
-
240
- (result & 0xFF).chr
241
- end
261
+ def tiff_apply_prediction(data, colors, bpc, columns) # :nodoc:
262
+ bpr = (colors * bpc * columns + 7) >> 3
263
+ nrows = data.size / bpr
264
+ bitmask = (1 << bpc) - 1
265
+ result = Utils::BitWriter.new
242
266
 
243
- #
244
- # Choose the preferred value in a PNG paeth predictor given the left, up and up left samples.
245
- #
246
- def png_paeth_choose(left, up, upleft)
247
- p = left + up - upleft
248
- pa, pb, pc = (p - left).abs, (p - up).abs, (p - upleft).abs
249
-
250
- case [pa, pb, pc].min
251
- when pa then left
252
- when pb then up
253
- when pc then upleft
254
- end
255
- end
267
+ nrows.times do |irow|
268
+ line = Utils::BitReader.new(data[irow * bpr, bpr])
256
269
 
257
- def tiff_post_prediction(data, colors, bpc, columns) #:nodoc:
258
- tiff_apply_prediction(data, colors, bpc, columns, &:+)
259
- end
270
+ diffpixel = ::Array.new(colors, 0)
271
+ columns.times do
272
+ pixel = ::Array.new(colors) { line.read(bpc) }
273
+ diffpixel = diffpixel.zip(pixel).map! { |diff, c| yield(c, diff) & bitmask }
260
274
 
261
- def tiff_pre_prediction(data, colors, bpc, columns) #:nodoc:
262
- tiff_apply_prediction(data, colors, bpc, columns, &:-)
275
+ diffpixel.each do |c|
276
+ result.write(c, bpc)
263
277
  end
278
+ end
264
279
 
265
- def tiff_apply_prediction(data, colors, bpc, columns) #:nodoc:
266
- bpr = (colors * bpc * columns + 7) >> 3
267
- nrows = data.size / bpr
268
- bitmask = (1 << bpc) - 1
269
- result = Utils::BitWriter.new
270
-
271
- nrows.times do |irow|
272
- line = Utils::BitReader.new(data[irow * bpr, bpr])
273
-
274
- diffpixel = ::Array.new(colors, 0)
275
- columns.times do
276
- pixel = ::Array.new(colors) { line.read(bpc) }
277
- diffpixel = diffpixel.zip(pixel).map!{|diff, c| yield(c, diff) & bitmask}
278
-
279
- diffpixel.each do |c|
280
- result.write(c, bpc)
281
- end
282
- end
283
-
284
- result.final
285
- end
286
-
287
- result.final.to_s
288
- end
280
+ result.final
289
281
  end
290
282
 
283
+ result.final.to_s
284
+ end
291
285
  end
286
+ end
292
287
  end