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 info = querypdf(pdfdoc,request.page,request.size)
63 if info then
64 local bbox = info and info.boundingbox or { 0, 0, 0, 0 }
65 local height = bbox[4] - bbox[2]
66 local width = bbox[3] - bbox[1]
67 local rotation = info.rotation or 0
68 if rotation == 90 then
69 rotation, height, width = 3, width, height
70 elseif rotation == 180 then
71 rotation = 2
72 elseif rotation == 270 then
73 rotation, height, width = 1, width, height
74 elseif rotation == 1 or rotation == 3 then
75 height, width = width, height
76 else
77 rotation = 0
78 end
79 return {
80 filename = filename,
81
82 pages = pdfdoc.nofpages,
83 width = width,
84 height = height,
85 depth = 0,
86 colordepth = 0,
87 xres = 0,
88 yres = 0,
89 xsize = width,
90 ysize = height,
91 rotation = rotation,
92 pdfdoc = pdfdoc,
93 }
94 end
95 end
96 end
97 request.copyimage = function(t)
98 if not pdfdoc then
99 pdfdoc = t.pdfdoc
100 end
101 if pdfdoc then
102 local page = request.page
103 local copied = pdfdoc.nofcopied or 0
104 if not pdfdoc.copied[page] then
105 pdfdoc.copied[page] = true
106 copied = copied + 1
107 end
108 pdfdoc.nofcopied = copied
109 if trace_pdf then
110 report_pdf("copy page %i from image %a, %i pages copied",page,filename,copied)
111 end
112 local result = copypage(pdfdoc,page,nil,request.compact,request.width,request.height,request.attr,request.metadata)
113 if pdfdoc.nofcopied >= pdfdoc.nofpages then
114 if trace_pdf then
115 report_pdf("closing image %a, %i pages copied",filename,copied)
116 end
117 closepdf(pdfdoc)
118 pdfdoc = nil
119 t.pdfdoc = nil
120 end
121 return result
122 else
123
124 end
125 end
126 end
127 return genericchecker(data)
128end
129
130local function wrappedidentify(identify,filename,filetype)
131 local wrapup = function() report_inclusion("fatal error reading %a",filename) end
132 local _, result = xpcall(identify,wrapup,filename,filetype)
133 if result then
134 local xsize = result.xsize or 0
135 local ysize = result.ysize or 0
136 local xres = result.xres or 0
137 local yres = result.yres or 0
138 if xres == 0 or yres == 0 then
139 xres = 300
140 yres = 300
141 end
142 result.xsize = xsize
143 result.ysize = ysize
144 result.xres = xres
145 result.yres = yres
146 result.width = result.width or ((72/xres) * xsize / bpfactor)
147 result.height = result.height or ((72/yres) * ysize / bpfactor)
148 result.depth = result.depth or 0
149 result.filename = filename
150 result.colordepth = result.colordepth or 0
151 result.colorspace = result.colorspace or 0
152 result.rotation = result.rotation or 0
153 result.orientation = result.orientation or 0
154 result.transform = result.transform or 0
155 return result
156 else
157 return { error = "fatal error" }
158 end
159end
160
161function checkers.jpg(data)
162 local request = data.request
163 local used = data.used
164 if request and used and not request.scanimage then
165 local identify = graphics.identify
166 local found = false
167 request.scanimage = function(t)
168 local result = wrappedidentify(identify,t.filename,"jpg")
169 found = not result.error
170 return {
171 filename = result.filename,
172 width = result.width,
173 height = result.height,
174 depth = result.depth,
175 colordepth = result.colordepth,
176 xres = result.xres,
177 yres = result.yres,
178 xsize = result.xsize,
179 ysize = result.ysize,
180 colorspace = result.colorspace,
181 rotation = result.rotation,
182 orientation = result.orientation,
183 transform = result.transform,
184 }
185 end
186 request.copyimage = function(t)
187 if found then
188 found = false
189 return backends.codeinjections.jpg(t)
190 end
191 end
192 end
193 return genericchecker(data)
194end
195
196function checkers.jp2(data)
197 local request = data.request
198 local used = data.used
199 if request and used and not request.scanimage then
200 local identify = graphics.identify
201 local found = false
202 request.scanimage = function(t)
203 local result = wrappedidentify(identify,t.filename,"jp2")
204 found = not result.error
205 return {
206 filename = result.filename,
207 width = result.width,
208 height = result.height,
209 depth = result.depth,
210 colordepth = result.colordepth,
211 xres = result.xres,
212 yres = result.yres,
213 xsize = result.xsize,
214 ysize = result.ysize,
215 rotation = result.rotation,
216 colorspace = result.colorspace,
217 orientation = result.orientation,
218 transform = result.transform,
219 }
220 end
221 request.copyimage = function(t)
222 if found then
223 found = false
224 return backends.codeinjections.jp2(t)
225 end
226 end
227 end
228 return genericchecker(data)
229end
230
231function checkers.png(data)
232 local request = data.request
233 local used = data.used
234 if request and used and not request.scanimage then
235 local identify = graphics.identify
236 local found = false
237 request.scanimage = function(t)
238 local result = wrappedidentify(identify,t.filename,"png")
239 found = not result.error
240 return {
241 filename = result.filename,
242 width = result.width,
243 height = result.height,
244 depth = result.depth,
245 colordepth = result.colordepth,
246 xres = result.xres,
247 yres = result.yres,
248 xsize = result.xsize,
249 ysize = result.ysize,
250 rotation = result.rotation,
251 colorspace = result.colorspace,
252 tables = result.tables,
253 interlace = result.interlace,
254 filter = result.filter,
255 orientation = result.orientation,
256 transform = result.transform,
257 }
258 end
259 request.copyimage = function(t)
260 t.colorref = used.colorref
261 if found then
262 found = false
263 local ok, result = pcall(backends.codeinjections.png,t)
264 if ok then
265 return result
266 else
267 report_inclusion("bad bitmap image")
268 return placeholder()
269 end
270 end
271 end
272 end
273 return genericchecker(data)
274end
275 |