001: package com.nwalsh.xalan;
002:
003: import java.io.*;
004: import java.awt.*;
005: import java.awt.image.*;
006: import java.lang.Thread;
007: import java.util.StringTokenizer;
008:
009: import org.apache.xalan.extensions.ExpressionContext;
010:
011: /**
012: * <p>Saxon extension to examine intrinsic size of images</p>
013: *
014: * <p>$Id: ImageIntrinsics.java,v 1.1 2006/05/31 17:21:20 mbatchelor Exp $</p>
015: *
016: * <p>Copyright (C) 2002 Norman Walsh.</p>
017: *
018: * <p>This class provides a
019: * <a href="http://xml.apache.org/">Xalan</a>
020: * extension to find the intrinsic size of images.</p>
021: *
022: * <p><b>Change Log:</b></p>
023: * <dl>
024: * <dt>1.0</dt>
025: * <dd><p>Initial release.</p></dd>
026: * </dl>
027: *
028: * @author Norman Walsh
029: * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
030: *
031: * @version $Id: ImageIntrinsics.java,v 1.1 2006/05/31 17:21:20 mbatchelor Exp $
032: *
033: */
034: public class ImageIntrinsics implements ImageObserver {
035: boolean imageLoaded = false;
036: boolean imageFailed = false;
037: Image image = null;
038: int width = -1;
039: int depth = -1;
040:
041: /**
042: * <p>Constructor for ImageIntrinsics</p>
043: */
044: public ImageIntrinsics(ExpressionContext context, String imageFn) {
045: System.setProperty("java.awt.headless", "true");
046: image = Toolkit.getDefaultToolkit().getImage(imageFn);
047: width = image.getWidth(this );
048:
049: while (!imageFailed && (width == -1 || depth == -1)) {
050: try {
051: java.lang.Thread.currentThread().sleep(50);
052: } catch (Exception e) {
053: // nop;
054: }
055: width = image.getWidth(this );
056: depth = image.getHeight(this );
057: }
058:
059: if (imageFailed) {
060: // Maybe it's an EPS or PDF?
061: // FIXME: this code is crude
062: BufferedReader ir = null;
063: String line = null;
064: int lineLimit = 100;
065:
066: try {
067: ir = new BufferedReader(new FileReader(
068: new File(imageFn)));
069: line = ir.readLine();
070:
071: if (line != null && line.startsWith("%PDF-")) {
072: // We've got a PDF!
073: while (lineLimit > 0 && line != null) {
074: lineLimit--;
075: if (line.startsWith("/CropBox [")) {
076: line = line.substring(10);
077: if (line.indexOf("]") >= 0) {
078: line = line.substring(0, line
079: .indexOf("]"));
080: }
081: parseBox(line);
082: lineLimit = 0;
083: }
084: line = ir.readLine();
085: }
086: } else if (line != null && line.startsWith("%!")
087: && line.indexOf(" EPSF-") > 0) {
088: // We've got an EPS!
089: while (lineLimit > 0 && line != null) {
090: lineLimit--;
091: if (line.startsWith("%%BoundingBox: ")) {
092: line = line.substring(15);
093: parseBox(line);
094: lineLimit = 0;
095: }
096: line = ir.readLine();
097: }
098: }
099: } catch (Exception e) {
100: // nop;
101: }
102:
103: if (ir != null) {
104: try {
105: ir.close();
106: } catch (Exception e) {
107: // nop;
108: }
109: }
110: }
111: }
112:
113: public int getWidth(ExpressionContext context, int defaultWidth) {
114: if (width >= 0) {
115: return width;
116: } else {
117: return defaultWidth;
118: }
119: }
120:
121: public int getDepth(ExpressionContext context, int defaultDepth) {
122: if (depth >= 0) {
123: return depth;
124: } else {
125: return defaultDepth;
126: }
127: }
128:
129: private void parseBox(String line) {
130: int[] corners = new int[4];
131: int count = 0;
132:
133: StringTokenizer st = new StringTokenizer(line);
134: while (count < 4 && st.hasMoreTokens()) {
135: try {
136: corners[count++] = Integer.parseInt(st.nextToken());
137: } catch (Exception e) {
138: // nop;
139: }
140: }
141:
142: width = corners[2] - corners[0];
143: depth = corners[3] - corners[1];
144: }
145:
146: public boolean imageUpdate(Image img, int infoflags, int x, int y,
147: int width, int height) {
148: if ((infoflags & ImageObserver.ERROR) == ImageObserver.ERROR) {
149: imageFailed = true;
150: return false;
151: }
152:
153: // I really only care about the width and height, but if I return false as
154: // soon as those are available, the BufferedInputStream behind the loader
155: // gets closed too early.
156: int flags = ImageObserver.ALLBITS;
157: if ((infoflags & flags) == flags) {
158: return false;
159: } else {
160: return true;
161: }
162: }
163: }
|