1package com.nwalsh.xalan; 2 3import java.io.*; 4import java.awt.*; 5import java.awt.image.*; 6import java.lang.Thread; 7import java.util.StringTokenizer; 8 9import org.apache.xalan.extensions.ExpressionContext; 10 11/** 12 * <p>Xalan extension to examine intrinsic size of images</p> 13 * 14 * <p>$Id: ImageIntrinsics.java,v 1.1 2006/05/04 13:23:51 nwalsh Exp $</p> 15 * 16 * <p>Copyright (C) 2002 Norman Walsh.</p> 17 * 18 * <p>This class provides a 19 * <a href="http://xml.apache.org/xalan-j/">Xalan</a> 20 * extension to find the intrinsic size of images.</p> 21 * 22 * <p><b>Change Log:</b></p> 23 * <dl> 24 * <dt>1.0</dt> 25 * <dd><p>Initial release.</p></dd> 26 * </dl> 27 * 28 * @author Norman Walsh 29 * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a> 30 * 31 * @version $Id: ImageIntrinsics.java,v 1.1 2006/05/04 13:23:51 nwalsh Exp $ 32 * 33 */ 34public class ImageIntrinsics implements ImageObserver { 35 boolean imageLoaded = false; 36 boolean imageFailed = false; 37 Image image = null; 38 int width = -1; 39 int depth = -1; 40 41 /** 42 * <p>Constructor for ImageIntrinsics</p> 43 */ 44 public ImageIntrinsics(ExpressionContext context, String imageFn) { 45 System.setProperty("java.awt.headless","true"); 46 image = Toolkit.getDefaultToolkit().getImage (imageFn); 47 width = image.getWidth(this); 48 49 while (!imageFailed && (width == -1 || depth == -1)) { 50 try { 51 java.lang.Thread.currentThread().sleep(50); 52 } catch (Exception e) { 53 // nop; 54 } 55 width = image.getWidth(this); 56 depth = image.getHeight(this); 57 } 58 59 if (imageFailed) { 60 // Maybe it's an EPS or PDF? 61 // FIXME: this code is crude 62 BufferedReader ir = null; 63 String line = null; 64 int lineLimit = 100; 65 66 try { 67 ir = new BufferedReader(new FileReader(new File(imageFn))); 68 line = ir.readLine(); 69 70 if (line != null && line.startsWith("%PDF-")) { 71 // We've got a PDF! 72 while (lineLimit > 0 && line != null) { 73 lineLimit--; 74 if (line.startsWith("/CropBox [")) { 75 line = line.substring(10); 76 if (line.indexOf("]") >= 0) { 77 line = line.substring(0, line.indexOf("]")); 78 } 79 parseBox(line); 80 lineLimit = 0; 81 } 82 line = ir.readLine(); 83 } 84 } else if (line != null && line.startsWith("%!") && line.indexOf(" EPSF-") > 0) { 85 // We've got an EPS! 86 while (lineLimit > 0 && line != null) { 87 lineLimit--; 88 if (line.startsWith("%%BoundingBox: ")) { 89 line = line.substring(15); 90 parseBox(line); 91 lineLimit = 0; 92 } 93 line = ir.readLine(); 94 } 95 } 96 } catch (Exception e) { 97 // nop; 98 } 99 100 if (ir != null) { 101 try { 102 ir.close(); 103 } catch (Exception e) { 104 // nop; 105 } 106 } 107 } 108 } 109 110 public int getWidth(ExpressionContext context, int defaultWidth) { 111 if (width >= 0) { 112 return width; 113 } else { 114 return defaultWidth; 115 } 116 } 117 118 public int getDepth(ExpressionContext context, int defaultDepth) { 119 if (depth >= 0) { 120 return depth; 121 } else { 122 return defaultDepth; 123 } 124 } 125 126 private void parseBox(String line) { 127 int [] corners = new int [4]; 128 int count = 0; 129 130 StringTokenizer st = new StringTokenizer(line); 131 while (count < 4 && st.hasMoreTokens()) { 132 try { 133 corners[count++] = Integer.parseInt(st.nextToken()); 134 } catch (Exception e) { 135 // nop; 136 } 137 } 138 139 width = corners[2] - corners[0]; 140 depth = corners[3] - corners[1]; 141 } 142 143 public boolean imageUpdate(Image img, int infoflags, 144 int x, int y, int width, int height) { 145 if ((infoflags & ImageObserver.ERROR) == ImageObserver.ERROR) { 146 imageFailed = true; 147 return false; 148 } 149 150 // I really only care about the width and height, but if I return false as 151 // soon as those are available, the BufferedInputStream behind the loader 152 // gets closed too early. 153 int flags = ImageObserver.ALLBITS; 154 if ((infoflags & flags) == flags) { 155 return false; 156 } else { 157 return true; 158 } 159 } 160} 161