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