origami 1.2.7 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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,333 +1,328 @@
1
1
  =begin
2
2
 
3
- = File
4
- linearization.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
- class PDF
23
+ class PDF
29
24
 
30
- class LinearizationError < Exception #:nodoc:
31
- end
25
+ class LinearizationError < Error #:nodoc:
26
+ end
32
27
 
33
- #
34
- # Returns whether the current document is linearized.
35
- #
36
- def is_linearized?
37
- begin
38
- obj = @revisions.first.objects.sort_by{|obj| obj.file_offset}.first
39
- rescue
40
- return false
41
- end
28
+ #
29
+ # Returns whether the current document is linearized.
30
+ #
31
+ def linearized?
32
+ begin
33
+ first_obj = @revisions.first.objects.min_by{|obj| obj.file_offset}
34
+ rescue
35
+ return false
36
+ end
37
+
38
+ @revisions.size > 1 and first_obj.is_a?(Dictionary) and first_obj.has_key? :Linearized
39
+ end
42
40
 
43
- obj.is_a?(Dictionary) and obj.has_key? :Linearized
44
- end
41
+ #
42
+ # Tries to delinearize the document if it has been linearized.
43
+ # This operation is xrefs destructive, should be fixed in the future to merge tables.
44
+ #
45
+ def delinearize!
46
+ raise LinearizationError, 'Not a linearized document' unless self.linearized?
47
+
48
+ #
49
+ # Saves the first trailer.
50
+ #
51
+ prev_trailer = @revisions.first.trailer
52
+
53
+ lin_dict = @revisions.first.objects.min_by{|obj| obj.file_offset}
54
+ hints = lin_dict[:H]
55
+
56
+ #
57
+ # Removes hint streams used by linearization.
58
+ #
59
+ if hints.is_a?(::Array)
60
+ if hints.length > 0 and hints[0].is_a?(Integer)
61
+ hint_stream = get_object_by_offset(hints[0])
62
+ delete_object(hint_stream.reference) if hint_stream.is_a?(Stream)
63
+ end
64
+
65
+ if hints.length > 2 and hints[2].is_a?(Integer)
66
+ overflow_stream = get_object_by_offset(hints[2])
67
+ delete_object(overflow_stream.reference) if overflow_stream.is_a?(Stream)
68
+ end
69
+ end
70
+
71
+ #
72
+ # Update the trailer.
73
+ #
74
+ last_trailer = (@revisions.last.trailer ||= Trailer.new)
75
+
76
+ last_trailer.dictionary ||= Dictionary.new
77
+
78
+ if prev_trailer.has_dictionary?
79
+ last_trailer.dictionary =
80
+ last_trailer.dictionary.merge(prev_trailer.dictionary)
81
+ else
82
+ xrefstm = @revisions.last.xrefstm
83
+ raise LinearizationError,
84
+ 'Cannot find trailer info while delinearizing document' unless xrefstm.is_a?(XRefStream)
85
+
86
+ last_trailer.dictionary[:Root] = xrefstm[:Root]
87
+ last_trailer.dictionary[:Encrypt] = xrefstm[:Encrypt]
88
+ last_trailer.dictionary[:Info] = xrefstm[:Info]
89
+ last_trailer.dictionary[:ID] = xrefstm[:ID]
90
+ end
91
+
92
+ #
93
+ # Remove all xrefs.
94
+ # Fix: Should be merged instead.
95
+ #
96
+ remove_xrefs
97
+
98
+ #
99
+ # Remove the linearization revision.
100
+ #
101
+ @revisions.first.body.delete(lin_dict.reference)
102
+ @revisions.last.body.merge! @revisions.first.body
103
+
104
+ remove_revision(0)
105
+
106
+ self
107
+ end
108
+ end
45
109
 
46
110
  #
47
- # Tries to delinearize the document if it has been linearized.
48
- # This operation is xrefs destructive, should be fixed in the future to merge tables.
111
+ # Class representing a linearization dictionary.
49
112
  #
50
- def delinearize!
51
- raise LinearizationError, 'Not a linearized document' unless is_linearized?
52
-
53
- #
54
- # Saves the first trailer.
55
- #
56
- prev_trailer = @revisions.first.trailer
57
-
58
- lin_dict = @revisions.first.objects.first
59
- hints = lin_dict[:H]
60
-
61
- #
62
- # Removes hint streams used by linearization.
63
- #
64
- if hints.is_a?(::Array)
65
- if hints.length > 0 and hints[0].is_a?(Integer)
66
- hint_stream = get_object_by_offset(hints[0])
67
- delete_object(hint_stream.reference) if hint_stream.is_a?(Stream)
113
+ class Linearization < Dictionary
114
+ include StandardObject
115
+
116
+ field :Linearized, :Type => Real, :Default => 1.0, :Required => true
117
+ field :L, :Type => Integer, :Required => true
118
+ field :H, :Type => Array.of(Integer), :Required => true
119
+ field :O, :Type => Integer, :Required => true
120
+ field :E, :Type => Integer, :Required => true
121
+ field :N, :Type => Integer, :Required => true
122
+ field :T, :Type => Integer, :Required => true
123
+ field :P, :Type => Integer, :Default => 0
124
+
125
+ def initialize(hash = {}, parser = nil)
126
+ super(hash, parser)
127
+
128
+ set_indirect(true)
68
129
  end
130
+ end
131
+
132
+ class InvalidHintTableError < Error #:nodoc:
133
+ end
134
+
135
+ module HintTable
136
+ module ClassMethods
137
+ def header_item_size(number, size)
138
+ @header_items_size[number] = size
139
+ end
140
+
141
+ def get_header_item_size(number)
142
+ @header_items_size[number]
143
+ end
144
+
145
+ def entry_item_size(number, size)
146
+ @entry_items_size[number] = size
147
+ end
148
+
149
+ def get_entry_item_size(number)
150
+ @entry_items_size[number]
151
+ end
69
152
 
70
- if hints.length > 2 and hints[2].is_a?(Integer)
71
- overflow_stream = get_object_by_offset(hints[2])
72
- delete_object(overflow_stream.reference) if overflow_stream.is_a?(Stream)
153
+ def nb_header_items
154
+ @header_items_size.size
155
+ end
156
+
157
+ def nb_entry_items
158
+ @entry_items_size.size
159
+ end
73
160
  end
74
- end
75
-
76
- #
77
- # Update the trailer.
78
- #
79
- last_trailer = (@revisions.last.trailer ||= Trailer.new)
80
-
81
- last_trailer.dictionary ||= Dictionary.new
82
-
83
- if prev_trailer.has_dictionary?
84
- last_trailer.dictionary =
85
- last_trailer.dictionary.merge(prev_trailer.dictionary)
86
- else
87
- xrefstm = get_object_by_offset(last_trailer.startxref)
88
- raise LinearizationError,
89
- 'Cannot find trailer info while delinearizing document' unless xrefstm.is_a?(XRefStream)
90
-
91
- last_trailer.dictionary[:Root] = xrefstm[:Root]
92
- last_trailer.dictionary[:Encrypt] = xrefstm[:Encrypt]
93
- last_trailer.dictionary[:Info] = xrefstm[:Info]
94
- last_trailer.dictionary[:ID] = xrefstm[:ID]
95
- end
96
-
97
- #
98
- # Remove all xrefs.
99
- # Fix: Should be merged instead.
100
- #
101
- remove_xrefs
102
-
103
- #
104
- # Remove the linearization revision.
105
- #
106
- remove_revision(0)
107
-
108
- self
109
- end
110
161
 
111
- end
112
-
113
- #
114
- # Class representing a linearization dictionary.
115
- #
116
- class Linearization < Dictionary
117
- include StandardObject
118
-
119
- field :Linearized, :Type => Real, :Default => 1.0, :Required => true
120
- field :L, :Type => Integer, :Required => true
121
- field :H, :Type => Array, :Required => true
122
- field :O, :Type => Integer, :Required => true
123
- field :E, :Type => Integer, :Required => true
124
- field :N, :Type => Integer, :Required => true
125
- field :T, :Type => Integer, :Required => true
126
- field :P, :Type => Integer, :Default => 0
127
-
128
- def initialize(hash = {})
129
- super(hash, true)
130
- end
162
+ def self.included(receiver)
163
+ receiver.instance_variable_set(:@header_items_size, {})
164
+ receiver.instance_variable_set(:@entry_items_size, {})
165
+ receiver.extend(ClassMethods)
166
+ end
131
167
 
132
- end
168
+ attr_accessor :header_items
169
+ attr_accessor :entries
133
170
 
134
- class InvalidHintTableError < Exception #:nodoc:
135
- end
171
+ def initialize
172
+ @header_items = {}
173
+ @entries = []
174
+ end
136
175
 
137
- module HintTable
138
- module ClassMethods
139
- def header_item_size(number, size)
140
- @header_items_size[number] = size
141
- end
176
+ def to_s
177
+ data = ""
142
178
 
143
- def get_header_item_size(number)
144
- @header_items_size[number]
145
- end
179
+ nitems = self.class.nb_header_items
180
+ for no in (1..nitems)
181
+ unless @header_items.include?(no)
182
+ raise InvalidHintTableError, "Missing item #{no} in header section of #{self.class}"
183
+ end
146
184
 
147
- def entry_item_size(number, size)
148
- @entry_items_size[number] = size
149
- end
185
+ value = @header_items[no]
186
+ item_size = self.class.get_header_item_size(no)
150
187
 
151
- def get_entry_item_size(number)
152
- @entry_items_size[number]
153
- end
188
+ item_size = ((item_size + 7) >> 3) << 3
189
+ item_data = value.to_s(2)
190
+ item_data = "0" * (item_size - item_data.size) + item_data
154
191
 
155
- def nb_header_items
156
- @header_items_size.size
157
- end
192
+ data << [ item_data ].pack("B*")
193
+ end
158
194
 
159
- def nb_entry_items
160
- @entry_items_size.size
161
- end
162
- end
195
+ i = 0
196
+ nitems = self.class.nb_entry_items
197
+ @entries.each do |entry|
198
+ for no in (1..items)
199
+ unless entry.include?(no)
200
+ raise InvalidHintTableError, "Missing item #{no} in entry #{i} of #{self.class}"
201
+ end
163
202
 
164
- def self.included(receiver)
165
- receiver.instance_variable_set(:@header_items_size, {})
166
- receiver.instance_variable_set(:@entry_items_size, {})
167
- receiver.extend(ClassMethods)
168
- end
203
+ value = entry[no]
204
+ item_size = self.class.get_entry_item_size(no)
169
205
 
170
- attr_accessor :header_items
171
- attr_accessor :entries
206
+ item_size = ((item_size + 7) >> 3) << 3
207
+ item_data = value.to_s(2)
208
+ item_data = "0" * (item_size - item_data.size) + item_data
172
209
 
173
- def initialize
174
- @header_items = {}
175
- @entries = []
176
- end
210
+ data << [ item_data ].pack("B*")
211
+ end
177
212
 
178
- def to_s
179
- data = ""
213
+ i = i + 1
214
+ end
180
215
 
181
- nitems = self.class.nb_header_items
182
- for no in (1..nitems)
183
- unless @header_items.include?(no)
184
- raise InvalidHintTableError, "Missing item #{no} in header section of #{self.class}"
216
+ data
185
217
  end
186
218
 
187
- value = @header_items[no]
188
- item_size = self.class.get_header_item_size(no)
189
-
190
- item_size = ((item_size + 7) >> 3) << 3
191
- item_data = value.to_s(2)
192
- item_data = "0" * (item_size - item_data.size) + item_data
193
-
194
- data << [ item_data ].pack("B*")
195
- end
196
-
197
- i = 0
198
- nitems = self.class.nb_entry_items
199
- @entries.each do |entry|
200
- for no in (1..items)
201
- unless entry.include?(no)
202
- raise InvalidHintTableError, "Missing item #{no} in entry #{i} of #{self.class}"
203
- end
204
-
205
- value = entry[no]
206
- item_size = self.class.get_entry_item_size(no)
207
-
208
- item_size = ((item_size + 7) >> 3) << 3
209
- item_data = value.to_s(2)
210
- item_data = "0" * (item_size - item_data.size) + item_data
211
-
212
- data << [ item_data ].pack("B*")
219
+ class PageOffsetTable
220
+ include HintTable
221
+
222
+ header_item_size 1, 32
223
+ header_item_size 2, 32
224
+ header_item_size 3, 16
225
+ header_item_size 4, 32
226
+ header_item_size 5, 16
227
+ header_item_size 6, 32
228
+ header_item_size 7, 16
229
+ header_item_size 8, 32
230
+ header_item_size 9, 16
231
+ header_item_size 10, 16
232
+ header_item_size 11, 16
233
+ header_item_size 12, 16
234
+ header_item_size 13, 16
235
+
236
+ entry_item_size 1, 16
237
+ entry_item_size 2, 16
238
+ entry_item_size 3, 16
239
+ entry_item_size 4, 16
240
+ entry_item_size 5, 16
241
+ entry_item_size 6, 16
242
+ entry_item_size 7, 16
213
243
  end
214
244
 
215
- i = i + 1
216
- end
217
-
218
- data
219
- end
220
-
221
- class PageOffsetTable
222
- include HintTable
223
-
224
- header_item_size 1, 32
225
- header_item_size 2, 32
226
- header_item_size 3, 16
227
- header_item_size 4, 32
228
- header_item_size 5, 16
229
- header_item_size 6, 32
230
- header_item_size 7, 16
231
- header_item_size 8, 32
232
- header_item_size 9, 16
233
- header_item_size 10, 16
234
- header_item_size 11, 16
235
- header_item_size 12, 16
236
- header_item_size 13, 16
237
-
238
- entry_item_size 1, 16
239
- entry_item_size 2, 16
240
- entry_item_size 3, 16
241
- entry_item_size 4, 16
242
- entry_item_size 5, 16
243
- entry_item_size 6, 16
244
- entry_item_size 7, 16
245
+ class SharedObjectTable
246
+ include HintTable
247
+
248
+ header_item_size 1, 32
249
+ header_item_size 2, 32
250
+ header_item_size 3, 32
251
+ header_item_size 4, 32
252
+ header_item_size 5, 16
253
+ header_item_size 6, 32
254
+ header_item_size 7, 16
255
+
256
+ entry_item_size 1, 16
257
+ entry_item_size 2, 1
258
+ entry_item_size 3, 128
259
+ entry_item_size 4, 16
260
+ end
245
261
  end
246
262
 
247
- class SharedObjectTable
248
- include HintTable
249
-
250
- header_item_size 1, 32
251
- header_item_size 2, 32
252
- header_item_size 3, 32
253
- header_item_size 4, 32
254
- header_item_size 5, 16
255
- header_item_size 6, 32
256
- header_item_size 7, 16
257
-
258
- entry_item_size 1, 16
259
- entry_item_size 2, 1
260
- entry_item_size 3, 128
261
- entry_item_size 4, 16
263
+ class InvalidHintStreamObjectError < InvalidStreamObjectError #:nodoc:
262
264
  end
263
265
 
264
- end
265
-
266
- class InvalidHintStreamObjectError < InvalidStreamObjectError #:nodoc:
267
- end
268
-
269
- class HintStream < Stream
270
-
271
- attr_accessor :page_offset_table
272
- attr_accessor :shared_objects_table
273
- attr_accessor :thumbnails_table
274
- attr_accessor :outlines_table
275
- attr_accessor :threads_table
276
- attr_accessor :named_destinations_table
277
- attr_accessor :interactive_forms_table
278
- attr_accessor :information_dictionary_table
279
- attr_accessor :logical_structure_table
280
- attr_accessor :page_labels_table
281
- attr_accessor :renditions_table
282
- attr_accessor :embedded_files_table
283
-
284
- field :S, :Type => Integer, :Required => true # SHared objects
285
- field :T, :Type => Integer # Thumbnails
286
- field :O, :Type => Integer # Outlines
287
- field :A, :Type => Integer # Threads
288
- field :E, :Type => Integer # Named destinations
289
- field :V, :Type => Integer # Interactive forms
290
- field :I, :Type => Integer # Information dictionary
291
- field :C, :Type => Integer # Logical structure
292
- field :L, :Type => Integer # Page labels
293
- field :R, :Type => Integer # Renditions
294
- field :B, :Type => Integer # Embedded files
295
-
296
- def pre_build
297
- if @page_offset_table.nil?
298
- raise InvalidHintStreamObjectError, "No page offset hint table"
299
- end
300
-
301
- if @shared_objects_table.nil?
302
- raise InvalidHintStreamObjectError, "No shared objects hint table"
303
- end
304
-
305
- @data = ""
306
- save_table(@page_offset_table)
307
- save_table(@shared_objects_table, :S)
308
- save_table(@thumbnails_table, :T)
309
- save_table(@outlines_table, :O)
310
- save_table(@threads_table, :A)
311
- save_table(@named_destinations_table, :E)
312
- save_table(@interactive_forms_table, :V)
313
- save_table(@information_dictionary_table, :I)
314
- save_table(@logical_structure_table, :C)
315
- save_table(@page_labels_table, :L)
316
- save_table(@renditions_table, :R)
317
- save_table(@embedded_files_table, :B)
318
-
319
- super
320
- end
266
+ class HintStream < Stream
267
+ attr_accessor :page_offset_table
268
+ attr_accessor :shared_objects_table
269
+ attr_accessor :thumbnails_table
270
+ attr_accessor :outlines_table
271
+ attr_accessor :threads_table
272
+ attr_accessor :named_destinations_table
273
+ attr_accessor :interactive_forms_table
274
+ attr_accessor :information_dictionary_table
275
+ attr_accessor :logical_structure_table
276
+ attr_accessor :page_labels_table
277
+ attr_accessor :renditions_table
278
+ attr_accessor :embedded_files_table
279
+
280
+ field :S, :Type => Integer, :Required => true # Shared objects
281
+ field :T, :Type => Integer # Thumbnails
282
+ field :O, :Type => Integer # Outlines
283
+ field :A, :Type => Integer # Threads
284
+ field :E, :Type => Integer # Named destinations
285
+ field :V, :Type => Integer # Interactive forms
286
+ field :I, :Type => Integer # Information dictionary
287
+ field :C, :Type => Integer # Logical structure
288
+ field :L, :Type => Integer # Page labels
289
+ field :R, :Type => Integer # Renditions
290
+ field :B, :Type => Integer # Embedded files
291
+
292
+ def pre_build
293
+ if @page_offset_table.nil?
294
+ raise InvalidHintStreamObjectError, "No page offset hint table"
295
+ end
296
+
297
+ if @shared_objects_table.nil?
298
+ raise InvalidHintStreamObjectError, "No shared objects hint table"
299
+ end
300
+
301
+ @data = ""
302
+ save_table(@page_offset_table)
303
+ save_table(@shared_objects_table, :S)
304
+ save_table(@thumbnails_table, :T)
305
+ save_table(@outlines_table, :O)
306
+ save_table(@threads_table, :A)
307
+ save_table(@named_destinations_table, :E)
308
+ save_table(@interactive_forms_table, :V)
309
+ save_table(@information_dictionary_table, :I)
310
+ save_table(@logical_structure_table, :C)
311
+ save_table(@page_labels_table, :L)
312
+ save_table(@renditions_table, :R)
313
+ save_table(@embedded_files_table, :B)
314
+
315
+ super
316
+ end
321
317
 
322
- private
318
+ private
323
319
 
324
- def save_table(table, name = nil)
325
- unless table.nil?
326
- self[name] = @data.size if name
327
- @data << table.to_s
328
- end
320
+ def save_table(table, name = nil)
321
+ unless table.nil?
322
+ self[name] = @data.size if name
323
+ @data << table.to_s
324
+ end
325
+ end
329
326
  end
330
327
 
331
- end
332
-
333
328
  end