/* * Copyright (C) Jerry Huxtable 1998-2001. All rights reserved. */ package com.jhlabs.jai; import java.util.*; import java.io.*; import java.net.*; import java.awt.*; import java.awt.image.*; import java.awt.image.renderable.*; import javax.media.jai.*; import com.sun.media.jai.codec.*; import org.xml.sax.*; import org.xml.sax.helpers.*; public class XMLDescriptor extends OperationDescriptorImpl implements RenderedImageFactory { private static final String[][] resources = { {"GlobalName", "xml"}, {"LocalName", "xml"}, {"Vendor", "com.jhlabs"}, {"Description", "An operation that produces an operator graph from an XML description"}, {"DocURL", "http://www.jhlabs.com/XMLDescriptor.html"}, {"Version", "1.0"}, {"arg0Desc", "file"}, {"arg1Desc", "stream"}, }; private static final String[] paramNames = { "file", "stream", }; /** * The class types for the parameters of the "XML" operation. */ private static final Class[] paramClasses = { java.lang.String.class, java.io.InputStream.class, }; /** * The default parameter values for the "XML" operation * when using a ParameterBlockJAI. */ private static final Object[] paramDefaults = { null, null, }; private static boolean registered = false; public static void register() { if (!registered) { OperationRegistry or = JAI.getDefaultInstance().getOperationRegistry(); XMLDescriptor d = new XMLDescriptor(); String operationName = "xml"; String productName = "com.jhlabs"; or.registerOperationDescriptor(d, operationName); or.registerRIF(operationName, productName, d); registered = true; } } public XMLDescriptor() { super(resources, 0, paramClasses, paramNames, paramDefaults); } public RenderedImage create(ParameterBlock paramBlock, RenderingHints renderHints) { // System.out.println("XMLDescriptor.create"); if (!validateParameters(paramBlock)) return null; String xmlFile = (String)paramBlock.getObjectParameter(0); InputStream is = (InputStream)paramBlock.getObjectParameter(1); // System.out.println("XMLDescriptor.create: "+xmlFile); try { if (is == null) is = new BufferedInputStream( new FileInputStream(xmlFile) ); JAIHandler xr = new JAIHandler(); Parser xp = ParserFactory.makeParser(); xp.setDocumentHandler(xr); xp.parse(new InputSource(is)); System.out.println("XMLDescriptor.create: "+xr.getImage()); return xr.getImage(); } catch (Throwable t) { t.printStackTrace(); } return null; } public boolean validateParameters(ParameterBlock paramBlock) { // System.out.println("->XMLDescriptor.validateParameters()"); for (int i = 0; i < this.getNumParameters(); i++) { Object arg = paramBlock.getObjectParameter(i); /* if (arg == null) { return false; } */ if (i == 0 && !(arg == null || arg instanceof String)) return false; else if (i == 1 && !(arg == null || arg instanceof InputStream)) return false; } return true; } } class JAIHandler implements DocumentHandler { private OpNode root; private OpNode node; private Hashtable images = new Hashtable(); private OperationRegistry or = JAI.getDefaultInstance().getOperationRegistry(); private String mode = "rendered"; public JAIHandler() { } public void setDocumentLocator(Locator l) { } public void startDocument() throws SAXException { } public void endDocument() throws SAXException { } public void startElement(String tag, AttributeList attrs) throws SAXException { String s; if (tag.equals("jaiop")) { } else if (tag.equals("image")) { String opName = attrs.getValue("xj:op"); if (opName == null) throw new IllegalArgumentException("Missing operator name"); // System.out.println("op="+opName); OpNode n; n = new OpNode(opName); if (root == null) { root = n; } else if (node != null) { node.add(n); } node = n; ParameterBlock pb = new ParameterBlock(); RegistryElementDescriptor red = or.getDescriptor(mode, opName); if (red == null) throw new IllegalArgumentException("Operator "+opName+" was not found in the registry"); ParameterListDescriptor pld = red.getParameterListDescriptor(mode); int numParams = pld.getNumParameters(); Class[] classes = pld.getParamClasses(); Object[] defaults = pld.getParamDefaults(); String[] names = pld.getParamNames(); for (int i = 0; i < numParams; i++) { String param = attrs.getValue(names[i]); if (param == null) pb.add(defaults[i]); else { try { Object o = parseParameter(param, classes[i]); pb.add(o); // System.out.println(names[i]+"="+o); } catch (Throwable e) { throw new SAXException(e.toString()); } } } n.setParameters(pb); String name = attrs.getValue("xj:name"); if (name != null) { images.put(name, n); if (name.equals("root")) root = n; } } else if (tag.equals("imageref")) { String reference = attrs.getValue("xj:name"); if (reference == null) throw new IllegalArgumentException("Missing reference in imageref"); OpNode op = (OpNode)images.get(reference); if (op == null) throw new IllegalArgumentException("Reference '"+reference+"' not found"); OpNode n; n = new OpNode(op); if (root == null) { root = n; } else if (node != null) { node.add(n); } } else if (tag.equals("property")) { String name = attrs.getValue("xj:name"); if (name == null) throw new IllegalArgumentException("Missing name in property"); String value = attrs.getValue("xj:value"); if (value == null) throw new IllegalArgumentException("Missing value in property"); if (node == null) throw new IllegalArgumentException("No image for property"); node.setProperty(name, value); } } public void endElement(String tag) throws SAXException { if (tag.equals("image")) { if (node != null) node = node.getParent(); } else if (tag.equals("jaiop")) { root.dump(System.out, 0); root.create(); } } public void characters(char[] buf, int offset, int len) throws SAXException { } public void ignorableWhitespace(char[] buf, int offset, int len) throws SAXException { } public void processingInstruction(String target, String data) throws SAXException { } private String getStringValue(AttributeList attrs, String name, String defaultValue) { if (attrs != null) { name = attrs.getValue(name); if (name != null) return name; } return defaultValue; } private int getIntValue(AttributeList attrs, String name, int defaultValue) { if (attrs != null) { name = attrs.getValue(name); if (name != null) { try { return Integer.parseInt(name); } catch (NumberFormatException e) { } } } return defaultValue; } private Object parseParameter(String param, Class cl) throws IOException { if (cl == Float.class) return Float.valueOf(param); if (cl == Double.class) return Double.valueOf(param); if (cl == Integer.class) return Integer.valueOf(param); if (cl == Boolean.class) return Boolean.valueOf(param); if (cl == URL.class) return new URL(param); if (cl == Interpolation.class) { if (param.equals("bilinear")) return new InterpolationBilinear(); // if (param.equals("bicubic")) // return new InterpolationBicubic(); // if (param.equals("bicubic2")) // return new InterpolationBicubic2(); return new InterpolationNearest(); } if (cl == KernelJAI.class) { if (param.equals("floyd-steinberg")) return KernelJAI.ERROR_FILTER_FLOYD_STEINBERG; if (param.equals("jarvis")) return KernelJAI.ERROR_FILTER_JARVIS; if (param.equals("stucki")) return KernelJAI.ERROR_FILTER_STUCKI; if (param.equals("sobel-horizontal")) return KernelJAI.GRADIENT_MASK_SOBEL_HORIZONTAL; if (param.equals("sobel-vertical")) return KernelJAI.GRADIENT_MASK_SOBEL_VERTICAL; } if (cl == BorderExtender.class) return BorderExtender.createInstance(Integer.parseInt(param)); return param; } public PlanarImage getImage() { return root.getImage(); } } class OpNode { private String opName; private ParameterBlock parameters; private Vector children; private OpNode parent; private PlanarImage op; private OpNode ref; private Hashtable properties; public OpNode(String opName) { this.opName = opName; } public OpNode(OpNode ref) { this.ref = ref; } public void add(OpNode n) { if (children == null) children = new Vector(); children.add(n); n.parent = this; } public OpNode getParent() { return parent; } public void create() { if (ref != null) { ref.create(); op = ref.getImage(); return; } if (op == null) { if (children != null) { Iterator it = children.iterator(); while (it.hasNext()) { OpNode n = (OpNode)it.next(); n.create(); parameters.addSource(n.getImage()); } } op = JAI.create(opName, parameters); if (properties != null) { Enumeration e = properties.keys(); while (e.hasMoreElements()) { String name = (String)e.nextElement(); String value = (String)properties.get(name); op.setProperty(name, value); } } } } public PlanarImage getImage() { return op; } public void setParameters(ParameterBlock parameters) { this.parameters = parameters; } public ParameterBlock getParameters() { return parameters; } public void setProperty(String name, String value) { if (properties == null) properties = new Hashtable(); properties.put(name, value); } public void dump(PrintStream out, int indent) { for (int i = 0; i < indent; i++) out.print(" "); if (ref != null) { out.println("reference: "+ref.opName); return; } else if (opName != null) { out.println(opName); if (children != null) { Iterator it = children.iterator(); while (it.hasNext()) { OpNode n = (OpNode)it.next(); n.dump(out, indent+2); } } } else out.println("null node!"); } }