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.4 2005-08-30 08:14:58 draganr 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.4 2005-08-30 08:14:58 draganr 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: image = Toolkit.getDefaultToolkit().getImage(imageFn);
046: width = image.getWidth(this );
047:
048: while (!imageFailed && (width == -1 || depth == -1)) {
049: try {
050: java.lang.Thread.currentThread().sleep(50);
051: } catch (Exception e) {
052: // nop;
053: }
054: width = image.getWidth(this );
055: depth = image.getHeight(this );
056: }
057:
058: if (imageFailed) {
059: // Maybe it's an EPS or PDF?
060: // FIXME: this code is crude
061: BufferedReader ir = null;
062: String line = null;
063: int lineLimit = 100;
064:
065: try {
066: ir = new BufferedReader(new FileReader(
067: new File(imageFn)));
068: line = ir.readLine();
069:
070: if (line != null && line.startsWith("%PDF-")) {
071: // We've got a PDF!
072: while (lineLimit > 0 && line != null) {
073: lineLimit--;
074: if (line.startsWith("/CropBox [")) {
075: line = line.substring(10);
076: if (line.indexOf("]") >= 0) {
077: line = line.substring(0, line
078: .indexOf("]"));
079: }
080: parseBox(line);
081: lineLimit = 0;
082: }
083: line = ir.readLine();
084: }
085: } else if (line != null && line.startsWith("%!")
086: && line.indexOf(" EPSF-") > 0) {
087: // We've got an EPS!
088: while (lineLimit > 0 && line != null) {
089: lineLimit--;
090: if (line.startsWith("%%BoundingBox: ")) {
091: line = line.substring(15);
092: parseBox(line);
093: lineLimit = 0;
094: }
095: line = ir.readLine();
096: }
097: }
098: } catch (Exception e) {
099: // nop;
100: }
101:
102: if (ir != null) {
103: try {
104: ir.close();
105: } catch (Exception e) {
106: // nop;
107: }
108: }
109: }
110: }
111:
112: public int getWidth(ExpressionContext context, int defaultWidth) {
113: if (width >= 0) {
114: return width;
115: } else {
116: return defaultWidth;
117: }
118: }
119:
120: public int getDepth(ExpressionContext context, int defaultDepth) {
121: if (depth >= 0) {
122: return depth;
123: } else {
124: return defaultDepth;
125: }
126: }
127:
128: private void parseBox(String line) {
129: int[] corners = new int[4];
130: int count = 0;
131:
132: StringTokenizer st = new StringTokenizer(line);
133: while (count < 4 && st.hasMoreTokens()) {
134: try {
135: corners[count++] = Integer.parseInt(st.nextToken());
136: } catch (Exception e) {
137: // nop;
138: }
139: }
140:
141: width = corners[2] - corners[0];
142: depth = corners[3] - corners[1];
143: }
144:
145: public boolean imageUpdate(Image img, int infoflags, int x, int y,
146: int width, int height) {
147: if ((infoflags & ImageObserver.ERROR) == ImageObserver.ERROR) {
148: imageFailed = true;
149: return false;
150: }
151:
152: // I really only care about the width and height, but if I return false as
153: // soon as those are available, the BufferedInputStream behind the loader
154: // gets closed too early.
155: int flags = ImageObserver.ALLBITS;
156: if ((infoflags & flags) == flags) {
157: return false;
158: } else {
159: return true;
160: }
161: }
162: }
|