Mercurial > hg > digilib-old
comparison servlet/src/digilib/servlet/Scaler.java @ 122:a32e8c80e2f2
Servlet Version 1.10b1
- more intelligent handling of resolutions
- different handling of mo=lores
author | robcast |
---|---|
date | Wed, 11 Jun 2003 22:51:28 +0200 |
parents | 55bc0e928ac5 |
children | ed7c1e4dd177 |
comparison
equal
deleted
inserted
replaced
121:1ac2c5c6ec0e | 122:a32e8c80e2f2 |
---|---|
37 | 37 |
38 import digilib.Utils; | 38 import digilib.Utils; |
39 import digilib.auth.AuthOpException; | 39 import digilib.auth.AuthOpException; |
40 import digilib.auth.AuthOps; | 40 import digilib.auth.AuthOps; |
41 import digilib.image.DocuImage; | 41 import digilib.image.DocuImage; |
42 import digilib.image.DocuInfo; | |
43 import digilib.image.ImageLoaderDocuInfo; | |
42 import digilib.image.ImageOpException; | 44 import digilib.image.ImageOpException; |
43 import digilib.io.DocuDirCache; | 45 import digilib.io.DocuDirCache; |
44 import digilib.io.DocuFile; | 46 import digilib.io.DocuFile; |
45 import digilib.io.DocuFileset; | 47 import digilib.io.DocuFileset; |
46 import digilib.io.FileOpException; | 48 import digilib.io.FileOpException; |
54 */ | 56 */ |
55 //public class Scaler extends HttpServlet implements SingleThreadModel { | 57 //public class Scaler extends HttpServlet implements SingleThreadModel { |
56 public class Scaler extends HttpServlet { | 58 public class Scaler extends HttpServlet { |
57 | 59 |
58 // digilib servlet version (for all components) | 60 // digilib servlet version (for all components) |
59 public static final String dlVersion = "1.9b3"; | 61 public static final String dlVersion = "1.10b1"; |
60 | 62 |
61 // Utils instance with debuglevel | 63 // Utils instance with debuglevel |
62 Utils util; | 64 Utils util; |
63 // FileOps instance | 65 // FileOps instance |
64 FileOps fileOp; | 66 FileOps fileOp; |
166 | 168 |
167 // scale the image file to fit window size i.e. respect dw,dh | 169 // scale the image file to fit window size i.e. respect dw,dh |
168 boolean scaleToFit = true; | 170 boolean scaleToFit = true; |
169 // scale the image by a fixed factor only | 171 // scale the image by a fixed factor only |
170 boolean absoluteScale = false; | 172 boolean absoluteScale = false; |
171 // crop the image if needed | 173 // only crop the image to fit |
172 boolean cropToFit = true; | 174 boolean cropToFit = false; |
173 // use heuristics (GIF?) to scale or send as is | 175 // try different resolution images automatically |
174 boolean autoScale = true; | 176 boolean autoRes = true; |
175 // try prescaled images first | 177 // use hires images (if autoRes == false) |
176 boolean preScaledFirst = true; | 178 boolean hiresOnly = false; |
177 // interpolation to use for scaling | 179 // interpolation to use for scaling |
178 int scaleQual = 0; | 180 int scaleQual = 0; |
179 // send html error message (or image file) | 181 // send html error message (or image file) |
180 boolean errorMsgHtml = false; | 182 boolean errorMsgHtml = false; |
181 // mirror the image | 183 // mirror the image |
192 | 194 |
193 // destination image width | 195 // destination image width |
194 int paramDW = dlRequest.getDw(); | 196 int paramDW = dlRequest.getDw(); |
195 // destination image height | 197 // destination image height |
196 int paramDH = dlRequest.getDh(); | 198 int paramDH = dlRequest.getDh(); |
199 // dw and dh shouldn't be empty, if they are, set dw=dh | |
200 if (paramDW <= 0) { | |
201 paramDW = paramDH; | |
202 } | |
203 if (paramDH <= 0) { | |
204 paramDH = paramDW; | |
205 } | |
197 // relative area x_offset (0..1) | 206 // relative area x_offset (0..1) |
198 double paramWX = dlRequest.getWx(); | 207 double paramWX = dlRequest.getWx(); |
199 // relative area y_offset | 208 // relative area y_offset |
200 double paramWY = dlRequest.getWy(); | 209 double paramWY = dlRequest.getWy(); |
201 // relative area width (0..1) | 210 // relative area width (0..1) |
220 */ | 229 */ |
221 if (dlRequest.isOption("clip")) { | 230 if (dlRequest.isOption("clip")) { |
222 scaleToFit = false; | 231 scaleToFit = false; |
223 absoluteScale = false; | 232 absoluteScale = false; |
224 cropToFit = true; | 233 cropToFit = true; |
225 autoScale = false; | 234 autoRes = true; |
226 preScaledFirst = false; | |
227 } else if (dlRequest.isOption("fit")) { | 235 } else if (dlRequest.isOption("fit")) { |
228 scaleToFit = true; | 236 scaleToFit = true; |
229 absoluteScale = false; | 237 absoluteScale = false; |
230 cropToFit = true; | 238 cropToFit = false; |
231 autoScale = false; | 239 autoRes = true; |
232 } else if (dlRequest.isOption("scale")) { | 240 } else if (dlRequest.isOption("scale")) { |
233 scaleToFit = false; | 241 scaleToFit = false; |
234 absoluteScale = true; | 242 absoluteScale = true; |
235 cropToFit = true; | 243 cropToFit = false; |
236 autoScale = false; | 244 autoRes = false; |
237 preScaledFirst = false; | 245 hiresOnly = true; |
238 } else if (dlRequest.isOption("file")) { | 246 } else if (dlRequest.isOption("file")) { |
239 scaleToFit = false; | 247 scaleToFit = false; |
240 absoluteScale = false; | 248 absoluteScale = false; |
241 if (dlConfig.isSendFileAllowed()) { | 249 if (dlConfig.isSendFileAllowed()) { |
242 cropToFit = false; | 250 cropToFit = false; |
243 } else { | 251 } else { |
252 // crop to fit if send file not allowed | |
244 cropToFit = true; | 253 cropToFit = true; |
245 } | 254 } |
246 autoScale = false; | 255 autoRes = false; |
247 preScaledFirst = false; | 256 hiresOnly = true; |
248 } | 257 } |
249 // operation mode: "errtxt": error message in html, "errimg": error image | 258 // operation mode: "errtxt": error message in html, "errimg": error image |
250 if (dlRequest.isOption("errtxt")) { | 259 if (dlRequest.isOption("errtxt")) { |
251 errorMsgHtml = true; | 260 errorMsgHtml = true; |
252 } else if (dlRequest.isOption("errimg")) { | 261 } else if (dlRequest.isOption("errimg")) { |
259 scaleQual = 1; | 268 scaleQual = 1; |
260 } else if (dlRequest.isOption("q2")) { | 269 } else if (dlRequest.isOption("q2")) { |
261 scaleQual = 2; | 270 scaleQual = 2; |
262 } | 271 } |
263 // operation mode: "lores": try to use scaled image, "hires": use unscaled image | 272 // operation mode: "lores": try to use scaled image, "hires": use unscaled image |
273 // "autores": try best fitting resolution | |
264 if (dlRequest.isOption("lores")) { | 274 if (dlRequest.isOption("lores")) { |
265 preScaledFirst = true; | 275 autoRes = false; |
276 hiresOnly = false; | |
266 } else if (dlRequest.isOption("hires")) { | 277 } else if (dlRequest.isOption("hires")) { |
267 preScaledFirst = false; | 278 autoRes = false; |
279 hiresOnly = true; | |
280 } else if (dlRequest.isOption("autores")) { | |
281 autoRes = true; | |
268 } | 282 } |
269 | 283 |
270 //"big" try for all file/image actions | 284 //"big" try for all file/image actions |
271 try { | 285 try { |
272 | 286 |
273 // new DocuImage instance | 287 // new DocuImage instance |
274 DocuImage docuImage = dlConfig.getDocuImageInstance(); | 288 DocuImage docuImage = dlConfig.getDocuImageInstance(); |
275 if (docuImage == null) { | 289 if (docuImage == null) { |
276 throw new ImageOpException("Unable to load DocuImage class!"); | 290 throw new ImageOpException("Unable to load DocuImage class!"); |
277 } | 291 } |
292 | |
293 // new DocuInfo instance | |
294 DocuInfo docuInfo = new ImageLoaderDocuInfo(); | |
278 | 295 |
279 // set interpolation quality | 296 // set interpolation quality |
280 docuImage.setQuality(scaleQual); | 297 docuImage.setQuality(scaleQual); |
281 | 298 |
282 /* | 299 /* |
311 return; | 328 return; |
312 } | 329 } |
313 } | 330 } |
314 } | 331 } |
315 | 332 |
316 // find the file | 333 // find the file(set) |
317 DocuFile fileToLoad; | 334 DocuFile fileToLoad; |
318 DocuFileset fileset = | 335 DocuFileset fileset = |
319 dirCache.getFileset(loadPathName, dlRequest.getPn()); | 336 dirCache.getFileset(loadPathName, dlRequest.getPn()); |
320 if (fileset == null) { | 337 if (fileset == null) { |
321 throw new FileOpException( | 338 throw new FileOpException( |
324 + "(" | 341 + "(" |
325 + dlRequest.getPn() | 342 + dlRequest.getPn() |
326 + ") not found."); | 343 + ") not found."); |
327 } | 344 } |
328 | 345 |
329 // if it's zoomed, try hires version (to be optimized...) | 346 /* |
330 if ((paramWW < 1f) || (paramWH < 1f)) { | 347 * calculate expected source image size |
331 preScaledFirst = false; | 348 * |
332 } | 349 */ |
333 | 350 Dimension expectedSourceSize = new Dimension(); |
334 // simplistic selection of resolution | 351 if (scaleToFit) { |
335 if (preScaledFirst) { | 352 double scale = (1 / Math.min(paramWW, paramWH)) * paramWS; |
336 // get last element | 353 expectedSourceSize.setSize(paramDW * scale, paramDH * scale); |
337 fileToLoad = fileset.get(fileset.size() - 1); | |
338 } else { | 354 } else { |
339 // get first element | 355 expectedSourceSize.setSize( |
340 fileToLoad = fileset.get(0); | 356 paramDW * paramWS, |
357 paramDH * paramWS); | |
358 } | |
359 | |
360 /* | |
361 * select a resolution | |
362 */ | |
363 if (autoRes) { | |
364 // autores: use next bigger resolution | |
365 fileToLoad = | |
366 fileset.getNextBigger(expectedSourceSize, docuInfo); | |
367 if (fileToLoad == null) { | |
368 // this is the biggest we have | |
369 fileToLoad = fileset.get(0); | |
370 } | |
371 } else { | |
372 // enforced hires or lores | |
373 if (hiresOnly) { | |
374 // get first element | |
375 fileToLoad = fileset.get(0); | |
376 } else { | |
377 // enforced lores uses next smaller resolution | |
378 fileToLoad = | |
379 fileset.getNextSmaller(expectedSourceSize, docuInfo); | |
380 if (fileToLoad == null) { | |
381 // this is the smallest we have | |
382 fileToLoad = fileset.get(fileset.size() - 1); | |
383 } | |
384 } | |
341 } | 385 } |
342 util.dprintln(1, "Loading: " + fileToLoad.getFile()); | 386 util.dprintln(1, "Loading: " + fileToLoad.getFile()); |
343 | 387 |
344 // check the source image | 388 // check the source image |
345 docuImage.checkFile(fileToLoad); | 389 if (!fileToLoad.isChecked()) { |
390 fileToLoad.check(docuInfo); | |
391 } | |
346 // get the source image type | 392 // get the source image type |
347 mimeType = fileToLoad.getMimetype(); | 393 mimeType = fileToLoad.getMimetype(); |
348 | 394 boolean imageSendable = |
349 /* if autoScale and not zoomed and source is GIF/PNG | 395 mimeType.equals("image/jpeg") |
350 * then send as is. | 396 || mimeType.equals("image/png") |
397 || mimeType.equals("image/gif"); | |
398 | |
399 /* if not autoRes and image smaller than requested | |
400 * size then send as is. | |
351 * if not autoScale and not scaleToFit nor cropToFit | 401 * if not autoScale and not scaleToFit nor cropToFit |
352 * then send as is | 402 * then send as is (mo=file) |
353 */ | 403 */ |
354 if ((autoScale | 404 if ((!autoRes |
355 && (mimeType == "image/gif" || mimeType == "image/png") | 405 && imageSendable |
356 && (paramWW == 1f) | 406 && (fileToLoad.getSize().width <= expectedSourceSize.width) |
357 && (paramWH == 1f)) | 407 && (fileToLoad.getSize().height <= expectedSourceSize.height)) |
358 || (!autoScale && !scaleToFit && !cropToFit)) { | 408 || (!autoRes && !scaleToFit && !cropToFit)) { |
359 | 409 |
360 util.dprintln(1, "Sending File as is."); | 410 util.dprintln(1, "Sending File as is."); |
361 | 411 |
362 servletOp.sendFile(fileToLoad.getFile(), response); | 412 servletOp.sendFile(fileToLoad.getFile(), response); |
363 | 413 |