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.4 2005-08-30 08:14:58 draganr 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.4 2005-08-30 08:14:58 draganr 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: image = Toolkit.getDefaultToolkit().getImage(imageFn);
044: width = image.getWidth(this );
045:
046: while (!imageFailed && (width == -1 || depth == -1)) {
047: try {
048: java.lang.Thread.currentThread().sleep(50);
049: } catch (Exception e) {
050: // nop;
051: }
052: width = image.getWidth(this );
053: depth = image.getHeight(this );
054: }
055:
056: if (imageFailed) {
057: // Maybe it's an EPS or PDF?
058: // FIXME: this code is crude
059: BufferedReader ir = null;
060: String line = null;
061: int lineLimit = 100;
062:
063: try {
064: ir = new BufferedReader(new FileReader(
065: new File(imageFn)));
066: line = ir.readLine();
067:
068: if (line != null && line.startsWith("%PDF-")) {
069: // We've got a PDF!
070: while (lineLimit > 0 && line != null) {
071: lineLimit--;
072: if (line.startsWith("/CropBox [")) {
073: line = line.substring(10);
074: if (line.indexOf("]") >= 0) {
075: line = line.substring(0, line
076: .indexOf("]"));
077: }
078: parseBox(line);
079: lineLimit = 0;
080: }
081: line = ir.readLine();
082: }
083: } else if (line != null && line.startsWith("%!")
084: && line.indexOf(" EPSF-") > 0) {
085: // We've got an EPS!
086: while (lineLimit > 0 && line != null) {
087: lineLimit--;
088: if (line.startsWith("%%BoundingBox: ")) {
089: line = line.substring(15);
090: parseBox(line);
091: lineLimit = 0;
092: }
093: line = ir.readLine();
094: }
095: }
096: } catch (Exception e) {
097: // nop;
098: }
099:
100: if (ir != null) {
101: try {
102: ir.close();
103: } catch (Exception e) {
104: // nop;
105: }
106: }
107: }
108: }
109:
110: public int getWidth(int defaultWidth) {
111: if (width >= 0) {
112: return width;
113: } else {
114: return defaultWidth;
115: }
116: }
117:
118: public int getDepth(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, int x, int y,
144: 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: }
|