origami 1.0.2
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.
- data/COPYING.LESSER +165 -0
- data/README +77 -0
- data/VERSION +1 -0
- data/bin/config/pdfcop.conf.yml +237 -0
- data/bin/gui/about.rb +46 -0
- data/bin/gui/config.rb +132 -0
- data/bin/gui/file.rb +385 -0
- data/bin/gui/hexdump.rb +74 -0
- data/bin/gui/hexview.rb +91 -0
- data/bin/gui/imgview.rb +72 -0
- data/bin/gui/menu.rb +392 -0
- data/bin/gui/properties.rb +132 -0
- data/bin/gui/signing.rb +635 -0
- data/bin/gui/textview.rb +107 -0
- data/bin/gui/treeview.rb +409 -0
- data/bin/gui/walker.rb +282 -0
- data/bin/gui/xrefs.rb +79 -0
- data/bin/pdf2graph +121 -0
- data/bin/pdf2ruby +353 -0
- data/bin/pdfcocoon +104 -0
- data/bin/pdfcop +455 -0
- data/bin/pdfdecompress +104 -0
- data/bin/pdfdecrypt +95 -0
- data/bin/pdfencrypt +112 -0
- data/bin/pdfextract +221 -0
- data/bin/pdfmetadata +123 -0
- data/bin/pdfsh +13 -0
- data/bin/pdfwalker +7 -0
- data/bin/shell/.irbrc +104 -0
- data/bin/shell/console.rb +136 -0
- data/bin/shell/hexdump.rb +83 -0
- data/origami.rb +36 -0
- data/origami/3d.rb +239 -0
- data/origami/acroform.rb +321 -0
- data/origami/actions.rb +299 -0
- data/origami/adobe/fdf.rb +259 -0
- data/origami/adobe/ppklite.rb +489 -0
- data/origami/annotations.rb +775 -0
- data/origami/array.rb +187 -0
- data/origami/boolean.rb +101 -0
- data/origami/catalog.rb +486 -0
- data/origami/destinations.rb +213 -0
- data/origami/dictionary.rb +188 -0
- data/origami/docmdp.rb +96 -0
- data/origami/encryption.rb +1293 -0
- data/origami/export.rb +283 -0
- data/origami/file.rb +222 -0
- data/origami/filters.rb +250 -0
- data/origami/filters/ascii.rb +189 -0
- data/origami/filters/ccitt.rb +515 -0
- data/origami/filters/crypt.rb +47 -0
- data/origami/filters/dct.rb +61 -0
- data/origami/filters/flate.rb +112 -0
- data/origami/filters/jbig2.rb +63 -0
- data/origami/filters/jpx.rb +53 -0
- data/origami/filters/lzw.rb +195 -0
- data/origami/filters/predictors.rb +276 -0
- data/origami/filters/runlength.rb +117 -0
- data/origami/font.rb +209 -0
- data/origami/functions.rb +93 -0
- data/origami/graphics.rb +33 -0
- data/origami/graphics/colors.rb +191 -0
- data/origami/graphics/instruction.rb +126 -0
- data/origami/graphics/path.rb +154 -0
- data/origami/graphics/patterns.rb +180 -0
- data/origami/graphics/state.rb +164 -0
- data/origami/graphics/text.rb +224 -0
- data/origami/graphics/xobject.rb +493 -0
- data/origami/header.rb +90 -0
- data/origami/linearization.rb +318 -0
- data/origami/metadata.rb +114 -0
- data/origami/name.rb +170 -0
- data/origami/null.rb +75 -0
- data/origami/numeric.rb +188 -0
- data/origami/obfuscation.rb +233 -0
- data/origami/object.rb +527 -0
- data/origami/outline.rb +59 -0
- data/origami/page.rb +559 -0
- data/origami/parser.rb +268 -0
- data/origami/parsers/fdf.rb +45 -0
- data/origami/parsers/pdf.rb +27 -0
- data/origami/parsers/pdf/linear.rb +113 -0
- data/origami/parsers/ppklite.rb +86 -0
- data/origami/pdf.rb +1144 -0
- data/origami/reference.rb +113 -0
- data/origami/signature.rb +474 -0
- data/origami/stream.rb +575 -0
- data/origami/string.rb +416 -0
- data/origami/trailer.rb +173 -0
- data/origami/webcapture.rb +87 -0
- data/origami/xfa.rb +3027 -0
- data/origami/xreftable.rb +447 -0
- data/templates/patterns.rb +66 -0
- data/templates/widgets.rb +173 -0
- data/templates/xdp.rb +92 -0
- data/tests/dataset/test.dummycrt +28 -0
- data/tests/dataset/test.dummykey +27 -0
- data/tests/tc_actions.rb +32 -0
- data/tests/tc_annotations.rb +85 -0
- data/tests/tc_pages.rb +37 -0
- data/tests/tc_pdfattach.rb +24 -0
- data/tests/tc_pdfencrypt.rb +110 -0
- data/tests/tc_pdfnew.rb +32 -0
- data/tests/tc_pdfparse.rb +98 -0
- data/tests/tc_pdfsig.rb +37 -0
- data/tests/tc_streams.rb +129 -0
- data/tests/ts_pdf.rb +45 -0
- metadata +193 -0
data/origami/export.rb
ADDED
@@ -0,0 +1,283 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
= File
|
4
|
+
export.rb
|
5
|
+
|
6
|
+
= Info
|
7
|
+
This file is part of Origami, PDF manipulation framework for Ruby
|
8
|
+
Copyright (C) 2010 Guillaume DelugrÈ <guillaume@security-labs.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/>.
|
23
|
+
|
24
|
+
=end
|
25
|
+
|
26
|
+
module Origami
|
27
|
+
|
28
|
+
class PDF
|
29
|
+
|
30
|
+
#
|
31
|
+
# Exports the document to a dot Graphiz file.
|
32
|
+
# _filename_:: The path where to save the file.
|
33
|
+
#
|
34
|
+
def export_to_graph(filename)
|
35
|
+
|
36
|
+
def appearance(object) #:nodoc:
|
37
|
+
|
38
|
+
label = object.type.to_s
|
39
|
+
case object
|
40
|
+
when Catalog
|
41
|
+
fontcolor = "red"
|
42
|
+
color = "mistyrose"
|
43
|
+
shape = "ellipse"
|
44
|
+
when Name, Number
|
45
|
+
label = object.value
|
46
|
+
fontcolor = "brown"
|
47
|
+
color = "lightgoldenrodyellow"
|
48
|
+
shape = "polygon"
|
49
|
+
when String
|
50
|
+
label = object.value unless (object.is_binary_data? or object.length > 50)
|
51
|
+
fontcolor = "red"
|
52
|
+
color = "white"
|
53
|
+
shape = "polygon"
|
54
|
+
when Array
|
55
|
+
fontcolor = "darkgreen"
|
56
|
+
color = "lightcyan"
|
57
|
+
shape = "ellipse"
|
58
|
+
else
|
59
|
+
fontcolor = "blue"
|
60
|
+
color = "aliceblue"
|
61
|
+
shape = "ellipse"
|
62
|
+
end
|
63
|
+
|
64
|
+
{ :label => label, :fontcolor => fontcolor, :color => color, :shape => shape }
|
65
|
+
end
|
66
|
+
|
67
|
+
def add_edges(pdf, fd, object) #:nodoc:
|
68
|
+
|
69
|
+
if object.is_a?(Array) or object.is_a?(ObjectStream)
|
70
|
+
|
71
|
+
object.each { |subobj|
|
72
|
+
subobj = subobj.solve if subobj.is_a?(Reference)
|
73
|
+
fd << "\t#{object.object_id} -> #{subobj.object_id}\n" unless subobj.nil?
|
74
|
+
}
|
75
|
+
|
76
|
+
elsif object.is_a?(Dictionary)
|
77
|
+
|
78
|
+
object.each_pair { |name, subobj|
|
79
|
+
subobj = subobj.solve if subobj.is_a?(Reference)
|
80
|
+
fd << "\t#{object.object_id} -> #{subobj.object_id} [label=\"#{name.value}\",fontsize=9];\n" unless subobj.nil?
|
81
|
+
}
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
if object.is_a?(Stream)
|
86
|
+
|
87
|
+
object.dictionary.each_pair { |key, value|
|
88
|
+
value = value.solve if value.is_a?(Reference)
|
89
|
+
fd << "\t#{object.object_id} -> #{value.object_id} [label=\"#{key.value}\",fontsize=9];\n" unless value.nil?
|
90
|
+
}
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
graphname = "PDF" if graphname.nil? or graphname.empty?
|
97
|
+
fd = File.open(filename, "w")
|
98
|
+
|
99
|
+
begin
|
100
|
+
fd << "digraph #{graphname} {\n\n"
|
101
|
+
|
102
|
+
objects = self.objects(:include_keys => false).find_all{ |obj| not obj.is_a?(Reference) }
|
103
|
+
|
104
|
+
objects.each { |object|
|
105
|
+
attr = appearance(object)
|
106
|
+
|
107
|
+
fd << "\t#{object.object_id} [label=\"#{attr[:label]}\",shape=#{attr[:shape]},color=#{attr[:color]},style=filled,fontcolor=#{attr[:fontcolor]},fontsize=16];\n"
|
108
|
+
|
109
|
+
if object.is_a?(Stream)
|
110
|
+
|
111
|
+
object.dictionary.each { |value|
|
112
|
+
unless value.is_a?(Reference)
|
113
|
+
attr = appearance(value)
|
114
|
+
fd << "\t#{value.object_id} [label=\"#{attr[:label]}\",shape=#{attr[:shape]},color=#{attr[:color]},style=filled,fontcolor=#{attr[:fontcolor]},fontsize=16];\n"
|
115
|
+
end
|
116
|
+
}
|
117
|
+
|
118
|
+
end
|
119
|
+
|
120
|
+
add_edges(self, fd, object)
|
121
|
+
}
|
122
|
+
fd << "\n}"
|
123
|
+
ensure
|
124
|
+
fd.close
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
|
129
|
+
#
|
130
|
+
# Exports the document to a GraphML file.
|
131
|
+
# _filename_:: The path where to save the file.
|
132
|
+
#
|
133
|
+
def export_to_graphml(filename)
|
134
|
+
|
135
|
+
def declare_node(id, attr) #:nodoc:
|
136
|
+
" <node id=\"#{id}\">\n" <<
|
137
|
+
" <data key=\"d0\">\n" <<
|
138
|
+
" <y:ShapeNode>\n" <<
|
139
|
+
" <y:NodeLabel>#{attr[:label]}</y:NodeLabel>\n" <<
|
140
|
+
#~ " <y:Shape type=\"#{attr[:shape]}\"/>\n" <<
|
141
|
+
" </y:ShapeNode>\n" <<
|
142
|
+
" </data>\n" <<
|
143
|
+
" </node>\n"
|
144
|
+
end
|
145
|
+
|
146
|
+
def declare_edge(id, src, dest, label = nil) #:nodoc:
|
147
|
+
" <edge id=\"#{id}\" source=\"#{src}\" target=\"#{dest}\">\n" <<
|
148
|
+
" <data key=\"d1\">\n" <<
|
149
|
+
" <y:PolyLineEdge>\n" <<
|
150
|
+
" <y:LineStyle type=\"line\" width=\"1.0\" color=\"#000000\"/>\n" <<
|
151
|
+
" <y:Arrows source=\"none\" target=\"standard\"/>\n" <<
|
152
|
+
" <y:EdgeLabel>#{label.to_s}</y:EdgeLabel>\n" <<
|
153
|
+
" </y:PolyLineEdge>\n" <<
|
154
|
+
" </data>\n" <<
|
155
|
+
" </edge>\n"
|
156
|
+
end
|
157
|
+
|
158
|
+
def appearance(object) #:nodoc:
|
159
|
+
|
160
|
+
label = object.type.to_s
|
161
|
+
case object
|
162
|
+
when Catalog
|
163
|
+
fontcolor = "red"
|
164
|
+
color = "mistyrose"
|
165
|
+
shape = "doublecircle"
|
166
|
+
when Name, Number
|
167
|
+
label = object.value
|
168
|
+
fontcolor = "orange"
|
169
|
+
color = "lightgoldenrodyellow"
|
170
|
+
shape = "polygon"
|
171
|
+
when String
|
172
|
+
label = object.value unless (object.is_binary_data? or object.length > 50)
|
173
|
+
fontcolor = "red"
|
174
|
+
color = "white"
|
175
|
+
shape = "polygon"
|
176
|
+
when Array
|
177
|
+
fontcolor = "green"
|
178
|
+
color = "lightcyan"
|
179
|
+
shape = "ellipse"
|
180
|
+
else
|
181
|
+
fontcolor = "blue"
|
182
|
+
color = "aliceblue"
|
183
|
+
shape = "ellipse"
|
184
|
+
end
|
185
|
+
|
186
|
+
{ :label => label, :fontcolor => fontcolor, :color => color, :shape => shape }
|
187
|
+
end
|
188
|
+
|
189
|
+
def add_edges(pdf, fd, object, id) #:nodoc:
|
190
|
+
|
191
|
+
if object.is_a?(Array) or object.is_a?(ObjectStream)
|
192
|
+
|
193
|
+
object.each { |subobj|
|
194
|
+
|
195
|
+
subobj = subobj.solve if subobj.is_a?(Reference)
|
196
|
+
|
197
|
+
unless subobj.nil?
|
198
|
+
fd << declare_edge("e#{id}", "n#{object.object_id}", "n#{subobj.object_id}")
|
199
|
+
id = id + 1
|
200
|
+
end
|
201
|
+
}
|
202
|
+
|
203
|
+
elsif object.is_a?(Dictionary)
|
204
|
+
|
205
|
+
object.each_pair { |name, subobj|
|
206
|
+
|
207
|
+
subobj = subobj.solve if subobj.is_a?(Reference)
|
208
|
+
|
209
|
+
unless subobj.nil?
|
210
|
+
fd << declare_edge("e#{id}", "n#{object.object_id}", "n#{subobj.object_id}", name.value)
|
211
|
+
id = id + 1
|
212
|
+
end
|
213
|
+
}
|
214
|
+
|
215
|
+
end
|
216
|
+
|
217
|
+
if object.is_a?(Stream)
|
218
|
+
|
219
|
+
object.dictionary.each_pair { |key, value|
|
220
|
+
|
221
|
+
value = value.solve if value.is_a?(Reference)
|
222
|
+
|
223
|
+
unless value.nil?
|
224
|
+
fd << declare_edge("e#{id}", "n#{object.object_id}", "n#{value.object_id}", key.value)
|
225
|
+
id = id + 1
|
226
|
+
end
|
227
|
+
}
|
228
|
+
|
229
|
+
end
|
230
|
+
|
231
|
+
id
|
232
|
+
end
|
233
|
+
|
234
|
+
@@edge_nb = 1
|
235
|
+
|
236
|
+
graphname = "PDF" if graphname.nil? or graphname.empty?
|
237
|
+
|
238
|
+
fd = File.open(filename, "w")
|
239
|
+
|
240
|
+
edge_nb = 1
|
241
|
+
begin
|
242
|
+
|
243
|
+
fd << '<?xml version="1.0" encoding="UTF-8"?>' << "\n"
|
244
|
+
fd << '<graphml xmlns="http://graphml.graphdrawing.org/xmlns/graphml"' << "\n"
|
245
|
+
fd << ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' << "\n"
|
246
|
+
fd << ' xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns/graphml ' << "\n"
|
247
|
+
fd << ' http://www.yworks.com/xml/schema/graphml/1.0/ygraphml.xsd"' << "\n"
|
248
|
+
fd << ' xmlns:y="http://www.yworks.com/xml/graphml">' << "\n"
|
249
|
+
fd << '<key id="d0" for="node" yfiles.type="nodegraphics"/>' << "\n"
|
250
|
+
fd << '<key id="d1" for="edge" yfiles.type="edgegraphics"/>' << "\n"
|
251
|
+
fd << "<graph id=\"#{graphname}\" edgedefault=\"directed\">\n"
|
252
|
+
|
253
|
+
objects = self.objects(:include_keys => false).find_all{ |obj| not obj.is_a?(Reference) }
|
254
|
+
|
255
|
+
objects.each { |object|
|
256
|
+
|
257
|
+
fd << declare_node("n#{object.object_id}", appearance(object))
|
258
|
+
|
259
|
+
if object.is_a?(Stream)
|
260
|
+
|
261
|
+
object.dictionary.each { |value|
|
262
|
+
|
263
|
+
unless value.is_a?(Reference)
|
264
|
+
fd << declare_node(value.object_id, appearance(value))
|
265
|
+
end
|
266
|
+
}
|
267
|
+
end
|
268
|
+
|
269
|
+
edge_nb = add_edges(self, fd, object, edge_nb)
|
270
|
+
}
|
271
|
+
|
272
|
+
fd << '</graph>' << "\n"
|
273
|
+
fd << '</graphml>'
|
274
|
+
|
275
|
+
ensure
|
276
|
+
fd.close
|
277
|
+
end
|
278
|
+
|
279
|
+
end
|
280
|
+
|
281
|
+
end
|
282
|
+
|
283
|
+
end
|
data/origami/file.rb
ADDED
@@ -0,0 +1,222 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
= File
|
4
|
+
file.rb
|
5
|
+
|
6
|
+
= Info
|
7
|
+
This file is part of Origami, PDF manipulation framework for Ruby
|
8
|
+
Copyright (C) 2010 Guillaume Delugré <guillaume@security-labs.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/>.
|
23
|
+
|
24
|
+
=end
|
25
|
+
|
26
|
+
module Origami
|
27
|
+
|
28
|
+
class PDF
|
29
|
+
|
30
|
+
#
|
31
|
+
# Attachs an embedded file to the PDF.
|
32
|
+
# _path_:: The path to the file to attach.
|
33
|
+
# _options_:: A set of options to configure the attachment.
|
34
|
+
#
|
35
|
+
def attach_file(path, options = {})
|
36
|
+
|
37
|
+
#
|
38
|
+
# Default options.
|
39
|
+
#
|
40
|
+
params =
|
41
|
+
{
|
42
|
+
:Register => true, # Shall the file be registered in the name directory ?
|
43
|
+
:EmbeddedName => nil, # The inner filename of the attachment.
|
44
|
+
:Filter => :FlateDecode # The stream filter used to store data.
|
45
|
+
}.update(options)
|
46
|
+
|
47
|
+
if path.respond_to?(:read)
|
48
|
+
fd = path
|
49
|
+
params[:EmbeddedName] ||= ''
|
50
|
+
else
|
51
|
+
fd = File.open(path, 'r').binmode
|
52
|
+
params[:EmbeddedName] ||= File.basename(path)
|
53
|
+
end
|
54
|
+
|
55
|
+
fstream = EmbeddedFileStream.new
|
56
|
+
fstream.data = fd.read
|
57
|
+
fstream.setFilter(params[:Filter])
|
58
|
+
|
59
|
+
name = params[:EmbeddedName]
|
60
|
+
fspec = FileSpec.new.setType(:Filespec).setF(name.dup).setEF(
|
61
|
+
FileSpec.new(:F => fstream)
|
62
|
+
)
|
63
|
+
|
64
|
+
register(
|
65
|
+
Names::Root::EMBEDDEDFILES,
|
66
|
+
name.dup,
|
67
|
+
fspec
|
68
|
+
) if params[:Register] == true
|
69
|
+
|
70
|
+
fd.close
|
71
|
+
|
72
|
+
fspec
|
73
|
+
end
|
74
|
+
|
75
|
+
#
|
76
|
+
# Lookup embedded file in the embedded files name directory.
|
77
|
+
#
|
78
|
+
def get_embedded_file_by_name(name)
|
79
|
+
resolve_name Names::Root::EMBEDDEDFILES, name
|
80
|
+
end
|
81
|
+
|
82
|
+
#
|
83
|
+
# Calls block for each named embedded file.
|
84
|
+
#
|
85
|
+
def each_named_embedded_file(&b)
|
86
|
+
each_name(Names::Root::EMBEDDEDFILES, &b)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
#
|
91
|
+
# Class used to convert system-dependent pathes into PDF pathes.
|
92
|
+
# PDF path specification offers a single form for representing file pathes over operating systems.
|
93
|
+
#
|
94
|
+
class Filename
|
95
|
+
|
96
|
+
class << self
|
97
|
+
|
98
|
+
#
|
99
|
+
# Converts UNIX file path into PDF file path.
|
100
|
+
#
|
101
|
+
def Unix(file)
|
102
|
+
ByteString.new(file)
|
103
|
+
end
|
104
|
+
|
105
|
+
#
|
106
|
+
# Converts MacOS file path into PDF file path.
|
107
|
+
#
|
108
|
+
def Mac(file)
|
109
|
+
ByteString.new("/" + file.gsub(":", "/"))
|
110
|
+
end
|
111
|
+
|
112
|
+
#
|
113
|
+
# Converts Windows file path into PDF file path.
|
114
|
+
#
|
115
|
+
def DOS(file)
|
116
|
+
path = ""
|
117
|
+
# Absolute vs relative path
|
118
|
+
if file.include? ":"
|
119
|
+
path << "/"
|
120
|
+
file.sub!(":","")
|
121
|
+
end
|
122
|
+
|
123
|
+
file.gsub!("\\", "/")
|
124
|
+
ByteString.new(path + file)
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
130
|
+
|
131
|
+
|
132
|
+
#
|
133
|
+
# Class representing a file specification.
|
134
|
+
# File specifications can be used to reference external files, as well as embedded files and URIs.
|
135
|
+
#
|
136
|
+
class FileSpec < Dictionary
|
137
|
+
|
138
|
+
include StandardObject
|
139
|
+
|
140
|
+
field :Type, :Type => Name, :Default => :FileSpec
|
141
|
+
field :FS, :Type => Name, :Default => :URL
|
142
|
+
field :F, :Type => [ ByteString, Stream ]
|
143
|
+
field :UF, :Type => String
|
144
|
+
field :DOS, :Type => ByteString
|
145
|
+
field :Mac, :Type => ByteString
|
146
|
+
field :Unix, :Type => ByteString
|
147
|
+
field :ID, :Type => Array
|
148
|
+
field :V, :Type => Boolean, :Default => false, :Version => "1.2"
|
149
|
+
field :EF, :Type => Dictionary, :Version => "1.3"
|
150
|
+
field :RF, :Type => Dictionary, :Version => "1.3"
|
151
|
+
field :Desc, :Type => ByteString, :Version => "1.6"
|
152
|
+
field :CI, :Type => Dictionary, :Version => "1.7"
|
153
|
+
field :Thumb, :Type => Stream, :Version => "1.7", :ExtensionLevel => 3
|
154
|
+
|
155
|
+
end
|
156
|
+
|
157
|
+
#
|
158
|
+
# Class representing a Uniform Resource Locator (URL)
|
159
|
+
#
|
160
|
+
class URL < FileSpec
|
161
|
+
|
162
|
+
field :Type, :Type => Name, :Default => :URL, :Required => true
|
163
|
+
|
164
|
+
def initialize(url)
|
165
|
+
super(:F => url)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
#
|
170
|
+
# A class representing a file outside the current PDF file.
|
171
|
+
#
|
172
|
+
class ExternalFile < FileSpec
|
173
|
+
|
174
|
+
field :Type, :Type => Name, :Default => :FileSpec, :Required => true
|
175
|
+
|
176
|
+
#
|
177
|
+
# Creates a new external file specification.
|
178
|
+
# _dos_:: The Windows path to this file.
|
179
|
+
# _mac_:: The MacOS path to this file.
|
180
|
+
# _unix_:: The UNIX path to this file.
|
181
|
+
#
|
182
|
+
def initialize(dos, mac = "", unix = "")
|
183
|
+
|
184
|
+
if not mac.empty? or not unix.empty?
|
185
|
+
super(:DOS => Filename.DOS(dos), :Mac => Filename.Mac(mac), :Unix => Filename.Unix(unix))
|
186
|
+
else
|
187
|
+
super(:F => dos)
|
188
|
+
end
|
189
|
+
|
190
|
+
end
|
191
|
+
|
192
|
+
end
|
193
|
+
|
194
|
+
#
|
195
|
+
# Class representing the data of an embedded file.
|
196
|
+
#
|
197
|
+
class EmbeddedFileStream < Stream
|
198
|
+
|
199
|
+
include StandardObject
|
200
|
+
|
201
|
+
field :Type, :Type => Name, :Default => :EmbeddedFile
|
202
|
+
field :Subtype, :Type => Name
|
203
|
+
field :Params, :Type => Dictionary
|
204
|
+
|
205
|
+
end
|
206
|
+
|
207
|
+
#
|
208
|
+
# Class representing parameters for a EmbeddedFileStream.
|
209
|
+
#
|
210
|
+
class EmbeddedFileParameters < Dictionary
|
211
|
+
|
212
|
+
include StandardObject
|
213
|
+
|
214
|
+
field :Size, :Type => Integer
|
215
|
+
field :CreationDate, :Type => ByteString
|
216
|
+
field :ModDate, :Type => ByteString
|
217
|
+
field :Mac, :Type => Dictionary
|
218
|
+
field :Checksum, :Type => String
|
219
|
+
|
220
|
+
end
|
221
|
+
|
222
|
+
end
|