1if not modules then modules = { } end modules ['grph-inc'] = {
2 version = 1.001,
3 comment = "companion to grph-inc.mkiv",
4 author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
5 copyright = "PRAGMA ADE / ConTeXt Development Team",
6 license = "see context related readme files"
7}
8
9local xpcall, pcall = xpcall, pcall
10
11local bpfactor = number.dimenfactors.bp
12
13local report = logs.reporter("graphics")
14local report_inclusion = logs.reporter("graphics","inclusion")
15local report_bitmap = logs.reporter("graphics","bitmap")
16local report_pdf = logs.reporter("graphics","pdf")
17
18local trace_pdf = false trackers.register("graphics.pdf", function(v) trace_pdf = v end)
19
20local checkers = figures.checkers
21local genericchecker = checkers.generic
22
23local placeholder = graphics.bitmaps.placeholder
24
25
26
27
28
29
30
31
32
33
34function checkers.pdf(data)
35 local request = data.request
36 local used = data.used
37 if request and used and not request.scanimage then
38 local image = lpdf.epdf.image
39 local openpdf = image.open
40 local closepdf = image.close
41 local querypdf = image.query
42 local copypage = image.copy
43 local pdfdoc = nil
44 local filename = nil
45 request.scanimage = function(t)
46 if pdfdoc then
47 if trace_pdf then
48 report_pdf("scan image %a",filename)
49 end
50 if not filename then
51 filename = pdfdoc.filename
52 end
53 else
54 filename = t.filename
55 if trace_pdf then
56 report_pdf("open and scan image %a",filename)
57 end
58 pdfdoc = openpdf(filename,request.userpassword,request.ownerpassword)
59 end
60 if pdfdoc then
61
62 local page = request.page
63 local label = request.pagelabel
64 local info = querypdf(pdfdoc,page,request.size,label)
65 if info then
66
67 local foundpage = info.pagenumber
68 if foundpage and foundpage ~= page then
69 if trace_pdf then
70 report_pdf("page label %a resolved to page %i in image %a",label,foundpage,filename)
71 end
72 else
73 foundpage = page
74 end
75 request.page = foundpage
76
77 local bbox = info and info.boundingbox or { 0, 0, 0, 0 }
78 local height = bbox[4] - bbox[2]
79 local width = bbox[3] - bbox[1]
80 local rotation = info.rotation or 0
81 if rotation == 90 then
82 rotation, height, width = 3, width, height
83 elseif rotation == 180 then
84 rotation = 2
85 elseif rotation == 270 then
86 rotation, height, width = 1, width, height
87 elseif rotation == 1 or rotation == 3 then
88 height, width = width, height
89 else
90 rotation = 0
91 end
92 return {
93 filename = filename,
94
95 page = foundpage,
96 pages = pdfdoc.nofpages,
97 width = width,
98 height = height,
99 depth = 0,
100 colordepth = 0,
101 xres = 0,
102 yres = 0,
103 xsize = width,
104 ysize = height,
105 rotation = rotation,
106 pdfdoc = pdfdoc,
107 }
108 end
109 end
110 end
111 request.copyimage = function(t)
112 if not pdfdoc then
113 pdfdoc = t.pdfdoc
114 end
115 if pdfdoc then
116 local page = request.page
117 local copied = pdfdoc.nofcopied or 0
118 if not pdfdoc.copied[page] then
119 pdfdoc.copied[page] = true
120 copied = copied + 1
121 end
122 pdfdoc.nofcopied = copied
123 if trace_pdf then
124 report_pdf("copy page %i from image %a, %i pages copied",page,filename,copied)
125 end
126 local result = copypage(pdfdoc,page,nil,request.compact,request.width,request.height,request.attr,request.metadata)
127 if pdfdoc.nofcopied >= pdfdoc.nofpages then
128 if trace_pdf then
129 report_pdf("closing image %a, %i pages copied",filename,copied)
130 end
131 closepdf(pdfdoc)
132 pdfdoc = nil
133 t.pdfdoc = nil
134 end
135 return result
136 else
137
138 end
139 end
140 end
141 return genericchecker(data)
142end
143
144local function wrappedidentify(identify,filename,filetype)
145 local wrapup = function() report_inclusion("fatal error reading %a",filename) end
146 local _, result = xpcall(identify,wrapup,filename,filetype)
147 if result then
148 local xsize = result.xsize or 0
149 local ysize = result.ysize or 0
150 local xres = result.xres or 0
151 local yres = result.yres or 0
152 if xres == 0 or yres == 0 then
153 xres = 300
154 yres = 300
155 end
156 result.xsize = xsize
157 result.ysize = ysize
158 result.xres = xres
159 result.yres = yres
160 result.width = result.width or ((72/xres) * xsize / bpfactor)
161 result.height = result.height or ((72/yres) * ysize / bpfactor)
162 result.depth = result.depth or 0
163 result.filename = filename
164 result.colordepth = result.colordepth or 0
165 result.colorspace = result.colorspace or 0
166 result.rotation = result.rotation or 0
167 result.orientation = result.orientation or 0
168 result.transform = result.transform or 0
169 return result
170 else
171 return { error = "fatal error" }
172 end
173end
174
175function checkers.jpg(data)
176 local request = data.request
177 local used = data.used
178 if request and used and not request.scanimage then
179 local identify = graphics.identify
180 local found = false
181 request.scanimage = function(t)
182 local result = wrappedidentify(identify,t.filename,"jpg")
183 found = not result.error
184 return {
185 filename = result.filename,
186 width = result.width,
187 height = result.height,
188 depth = result.depth,
189 colordepth = result.colordepth,
190 xres = result.xres,
191 yres = result.yres,
192 xsize = result.xsize,
193 ysize = result.ysize,
194 colorspace = result.colorspace,
195 rotation = result.rotation,
196 orientation = result.orientation,
197 transform = result.transform,
198 }
199 end
200 request.copyimage = function(t)
201 if found then
202 found = false
203 return backends.codeinjections.jpg(t)
204 end
205 end
206 end
207 return genericchecker(data)
208end
209
210function checkers.jp2(data)
211 local request = data.request
212 local used = data.used
213 if request and used and not request.scanimage then
214 local identify = graphics.identify
215 local found = false
216 request.scanimage = function(t)
217 local result = wrappedidentify(identify,t.filename,"jp2")
218 found = not result.error
219 return {
220 filename = result.filename,
221 width = result.width,
222 height = result.height,
223 depth = result.depth,
224 colordepth = result.colordepth,
225 xres = result.xres,
226 yres = result.yres,
227 xsize = result.xsize,
228 ysize = result.ysize,
229 rotation = result.rotation,
230 colorspace = result.colorspace,
231 orientation = result.orientation,
232 transform = result.transform,
233 }
234 end
235 request.copyimage = function(t)
236 if found then
237 found = false
238 return backends.codeinjections.jp2(t)
239 end
240 end
241 end
242 return genericchecker(data)
243end
244
245function checkers.png(data)
246 local request = data.request
247 local used = data.used
248 if request and used and not request.scanimage then
249 local identify = graphics.identify
250 local found = false
251 request.scanimage = function(t)
252 local result = wrappedidentify(identify,t.filename,"png")
253 found = not result.error
254 return {
255 filename = result.filename,
256 width = result.width,
257 height = result.height,
258 depth = result.depth,
259 colordepth = result.colordepth,
260 xres = result.xres,
261 yres = result.yres,
262 xsize = result.xsize,
263 ysize = result.ysize,
264 rotation = result.rotation,
265 colorspace = result.colorspace,
266 tables = result.tables,
267 interlace = result.interlace,
268 filter = result.filter,
269 orientation = result.orientation,
270 transform = result.transform,
271 }
272 end
273 request.copyimage = function(t)
274 t.colorref = used.colorref
275 if found then
276 found = false
277 local ok, result = pcall(backends.codeinjections.png,t)
278 if ok then
279 return result
280 else
281 report_inclusion("bad bitmap image")
282 return placeholder()
283 end
284 end
285 end
286 end
287 return genericchecker(data)
288end
289 |