comparison servlet/src/digilib/image/JAIDocuImage.java @ 470:16bd70715ac3

Improved performance of JAIDocuImage for large images - simulated subsampling by scaling
author robcast
date Wed, 15 Feb 2006 00:09:50 +0100
parents 0fc853d98820
children e758a49258e8
comparison
equal deleted inserted replaced
469:11e11fe4d680 470:16bd70715ac3
18 18
19 */ 19 */
20 20
21 package digilib.image; 21 package digilib.image;
22 22
23 import java.awt.Rectangle;
23 import java.awt.RenderingHints; 24 import java.awt.RenderingHints;
24 import java.awt.image.RenderedImage; 25 import java.awt.image.RenderedImage;
25 import java.awt.image.renderable.ParameterBlock; 26 import java.awt.image.renderable.ParameterBlock;
26 import java.io.File; 27 import java.io.File;
27 import java.io.IOException; 28 import java.io.IOException;
44 45
45 import digilib.io.FileOpException; 46 import digilib.io.FileOpException;
46 import digilib.io.FileOps; 47 import digilib.io.FileOps;
47 import digilib.io.ImageFile; 48 import digilib.io.ImageFile;
48 import digilib.io.ImageFileset; 49 import digilib.io.ImageFileset;
49 import javax.media.jai.TileCache;
50 50
51 /** A DocuImage implementation using Java Advanced Imaging Library. */ 51 /** A DocuImage implementation using Java Advanced Imaging Library. */
52 public class JAIDocuImage extends DocuImageImpl { 52 public class JAIDocuImage extends DocuImageImpl {
53 53
54 protected RenderedImage img; 54 protected RenderedImage img;
55 55
56 protected Interpolation interpol = null; 56 protected Interpolation interpol = null;
57 57
58 static { 58 /*
59 /* we could set our own tile cache size here 59 * static { // we could set our own tile cache size here TileCache tc =
60 TileCache tc = JAI.createTileCache(100*1024*1024); 60 * JAI.createTileCache(100*1024*1024);
61 JAI.getDefaultInstance().setTileCache(tc); 61 * JAI.getDefaultInstance().setTileCache(tc); }
62 */ 62 */
63 } 63
64 64 public boolean isSubimageSupported() {
65 return true;
66 }
67
68 /*
69 * Real setQuality implementation. Creates the correct Interpolation.
70 */
71 public void setQuality(int qual) {
72 quality = qual;
73 // setup interpolation quality
74 if (qual > 1) {
75 logger.debug("quality q2");
76 interpol = Interpolation.getInstance(Interpolation.INTERP_BICUBIC);
77 } else if (qual == 1) {
78 logger.debug("quality q1");
79 interpol = Interpolation.getInstance(Interpolation.INTERP_BILINEAR);
80 } else {
81 logger.debug("quality q0");
82 interpol = Interpolation.getInstance(Interpolation.INTERP_NEAREST);
83 }
84 }
85
65 /* returns a list of supported image formats */ 86 /* returns a list of supported image formats */
66 public Iterator getSupportedFormats() { 87 public Iterator getSupportedFormats() {
67 Enumeration codecs = ImageCodec.getCodecs(); 88 Enumeration codecs = ImageCodec.getCodecs();
68 List formats = new ArrayList(5); 89 List formats = new ArrayList(5);
69 for (Object codec = codecs.nextElement(); codecs.hasMoreElements(); codec = codecs 90 for (Object codec = codecs.nextElement(); codecs.hasMoreElements(); codec = codecs
70 .nextElement()) { 91 .nextElement()) {
71 logger.debug("known format:"+((ImageCodec) codec).getFormatName()); 92 logger
93 .debug("known format:"
94 + ((ImageCodec) codec).getFormatName());
72 formats.add(((ImageCodec) codec).getFormatName()); 95 formats.add(((ImageCodec) codec).getFormatName());
73 } 96 }
74 logger.debug("tilecachesize:"+JAI.getDefaultInstance().getTileCache().getMemoryCapacity()); 97 logger.debug("tilecachesize:"
98 + JAI.getDefaultInstance().getTileCache().getMemoryCapacity());
75 return formats.iterator(); 99 return formats.iterator();
76 } 100 }
77 101
78 /** Check image size and type and store in ImageFile f */ 102 /* Check image size and type and store in ImageFile f */
79 public boolean identify(ImageFile imgf) throws IOException { 103 public boolean identify(ImageFile imgf) throws IOException {
80 // try parent method first 104 // try parent method first
81 if (super.identify(imgf)) { 105 if (super.identify(imgf)) {
82 return true; 106 return true;
83 } 107 }
114 if (img == null) { 138 if (img == null) {
115 throw new FileOpException("Unable to load File!"); 139 throw new FileOpException("Unable to load File!");
116 } 140 }
117 } 141 }
118 142
143 /* Load an image file into the Object. */
144 public void loadSubimage(ImageFile f, Rectangle region, int subsample)
145 throws FileOpException {
146 logger.debug("loadSubimage");
147 img = JAI.create("fileload", f.getFile().getAbsolutePath());
148 if ((region.width < img.getWidth())
149 || (region.height < img.getHeight())) {
150 // setup Crop
151 ParameterBlock cp = new ParameterBlock();
152 cp.addSource(img);
153 cp.add((float) region.x);
154 cp.add((float) region.y);
155 cp.add((float) region.width);
156 cp.add((float) region.height);
157 logger.debug("loadSubimage: crop");
158 img = JAI.create("crop", cp);
159 }
160 if (subsample > 1) {
161 float sc = 1f / subsample;
162 ParameterBlockJAI sp = new ParameterBlockJAI("scale");
163 sp.addSource(img);
164 sp.setParameter("xScale", sc);
165 sp.setParameter("yScale", sc);
166 sp.setParameter("interpolation", Interpolation
167 .getInstance(Interpolation.INTERP_NEAREST));
168 // scale
169 logger.debug("loadSubimage: scale");
170 img = JAI.create("scale", sp);
171 }
172 }
173
119 /* Write the current image to an OutputStream. */ 174 /* Write the current image to an OutputStream. */
120 public void writeImage(String mt, OutputStream ostream) 175 public void writeImage(String mt, OutputStream ostream)
121 throws FileOpException { 176 throws FileOpException {
122 try { 177 try {
123 // setup output 178 // setup output
138 } catch (IOException e) { 193 } catch (IOException e) {
139 throw new FileOpException("Error writing image."); 194 throw new FileOpException("Error writing image.");
140 } 195 }
141 } 196 }
142 197
143 /*
144 * Real setQuality implementation. Creates the correct Interpolation.
145 */
146 public void setQuality(int qual) {
147 quality = qual;
148 // setup interpolation quality
149 if (qual > 1) {
150 logger.debug("quality q2");
151 interpol = Interpolation.getInstance(Interpolation.INTERP_BICUBIC);
152 } else if (qual == 1) {
153 logger.debug("quality q1");
154 interpol = Interpolation.getInstance(Interpolation.INTERP_BILINEAR);
155 } else {
156 logger.debug("quality q0");
157 interpol = Interpolation.getInstance(Interpolation.INTERP_NEAREST);
158 }
159 }
160
161 /** 198 /**
162 * The width of the curent image in pixel. 199 * The width of the curent image in pixel.
163 * 200 *
164 * @return Image width in pixels. 201 * @return Image width in pixels.
165 */ 202 */
193 scaleBinary((float) scale); 230 scaleBinary((float) scale);
194 } else if ((scale <= 0.5) && (quality > 1)) { 231 } else if ((scale <= 0.5) && (quality > 1)) {
195 /* 232 /*
196 * blur and "Scale" for downscaling color images 233 * blur and "Scale" for downscaling color images
197 */ 234 */
198 if ((scale <= 0.5) && (quality > 1)) { 235 if ((scale <= 0.5) && (quality > 1)) {
199 int bl = (int) Math.floor(1 / scale); 236 int bl = (int) Math.floor(1 / scale);
200 // don't blur more than 3 237 // don't blur more than 3
201 blur(Math.min(bl, 3)); 238 blur(Math.min(bl, 3));
202 } 239 }
203 scaleAll((float) scale); 240 scaleAll((float) scale);
204 } else { 241 } else {
205 /* 242 /*
206 * "Scale" for the rest 243 * "Scale" for the rest
207 */ 244 */