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,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