/* * Copyright (C) 2010 Brockmann Consult GmbH (info@brockmann-consult.de) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 3 of the License, or (at your option) * any later version. * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, see http://www.gnu.org/licenses/ */ package com.bc.ceres.jai.js; import org.mozilla.javascript.Context; import org.mozilla.javascript.Function; import org.mozilla.javascript.Scriptable; import org.mozilla.javascript.ScriptableObject; import javax.media.jai.EnumeratedParameter; import javax.media.jai.Interpolation; import javax.media.jai.JAI; import javax.media.jai.OperationDescriptor; import javax.media.jai.OperationRegistry; import javax.media.jai.ParameterListDescriptor; import javax.media.jai.PlanarImage; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JScrollPane; import java.awt.Image; import java.awt.image.RenderedImage; import java.awt.image.BufferedImage; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Locale; public class JsJai extends ScriptableObject { public JsJai() { construct(); } public JsJai(Scriptable scope, Scriptable prototype) { super(scope, prototype); construct(); } public String getClassName() { return "jai"; } @Override public Object getDefaultValue(Class aClass) { if (aClass == String.class) { return "[" + getClassName() + "]"; } else if (aClass == Boolean.class) { return false; } else if (aClass == Number.class) { return 0; } else if (aClass == Scriptable.class) { return this; } else { return null; } } private void construct() { final OperationRegistry operationRegistry = JAI.getDefaultInstance().getOperationRegistry(); final List<OperationDescriptor> operationDescriptors = (List<OperationDescriptor>) operationRegistry.getDescriptors(OperationDescriptor.class); for (OperationDescriptor operationDescriptor : operationDescriptors) { final JsJaiFunction jaiFunction = new JsJaiFunction(operationDescriptor); defineProperty(jaiFunction.getClassName(), jaiFunction, ScriptableObject.READONLY); final Field[] fields = operationDescriptor.getClass().getFields(); for (Field field : fields) { final int modifiers = field.getModifiers(); if (Modifier.isPublic(modifiers) && Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers)) { try { defineProperty(field.getName(), field.get(operationDescriptor), READONLY); } catch (IllegalAccessException e) { System.out.println("Error: operationDescriptor=" + operationDescriptor + ", field=" + field + ", e=" + e); } } } } defineProperty("INTERP_NEAREST", Interpolation.getInstance(Interpolation.INTERP_NEAREST), READONLY); defineProperty("INTERP_BILINEAR", Interpolation.getInstance(Interpolation.INTERP_BILINEAR), READONLY); defineProperty("INTERP_BICUBIC", Interpolation.getInstance(Interpolation.INTERP_BICUBIC), READONLY); defineProperty("INTERP_BICUBIC_2", Interpolation.getInstance(Interpolation.INTERP_BICUBIC_2), READONLY); defineFunctionProperties(new String[]{"show", "help"}, JsJai.class, ScriptableObject.DONTENUM); } static int frameId = 0; static HashMap<Integer, JFrame> frames = new HashMap<Integer, JFrame>(); public static int show(Context cx, Scriptable thisObj, Object[] args, Function funObj) { final RenderedImage renderedImage = args.length > 0 ? (RenderedImage) Context.jsToJava(args[0], RenderedImage.class) : null; int frameId = args.length > 1 ? (Integer) Context.jsToJava(args[1], Integer.class) : -1; final Image image; if (renderedImage instanceof PlanarImage) { image = ((PlanarImage) renderedImage).getAsBufferedImage(); } else if (renderedImage instanceof Image) { image = (Image) renderedImage; } else { image = new BufferedImage(512, 512, BufferedImage.TYPE_BYTE_GRAY); } JFrame frame = frames.get(frameId); if (frame != null) { frame.getContentPane().removeAll(); } else { frameId = JsJai.frameId++; frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); frames.put(frameId, frame); } frame.setTitle("Image #" + frameId); frame.getContentPane().add(new JScrollPane(new JLabel(new ImageIcon(image)))); frame.pack(); frame.setVisible(true); return frameId; } public static void help(Context cx, Scriptable thisObj, Object[] args, Function funObj) { if (args.length == 0) { final Object[] objects = thisObj.getIds(); for (Object object : objects) { System.out.println("jai." + object + " = " + thisObj.get(object.toString(), thisObj)); } printOperatorList(); } else { for (Object arg : args) { printOperatorUsage(Context.toString(arg)); } } } public static void printOperatorList() { OperationRegistry operationRegistry = JAI.getDefaultInstance().getOperationRegistry(); List<OperationDescriptor> descriptors = (List<OperationDescriptor>) operationRegistry.getDescriptors(OperationDescriptor.class); Collections.sort(descriptors, new Comparator<OperationDescriptor>() { public int compare(OperationDescriptor descriptor1, OperationDescriptor descriptor2) { return descriptor1.getName().compareTo(descriptor2.getName()); } }); int columnCount = 0; for (OperationDescriptor descriptor : descriptors) { columnCount = Math.max(columnCount, descriptor.getName().length()); } for (OperationDescriptor descriptor : descriptors) { String namePart = descriptor.getName(); if (namePart.length() < columnCount) { namePart += spaces(columnCount - namePart.length()); } String[][] resources = descriptor.getResources(Locale.getDefault()); String description = resources[3][1]; System.out.println(namePart + " - " + description); } } private static void printOperatorUsage(String name) { OperationRegistry operationRegistry = JAI.getDefaultInstance().getOperationRegistry(); OperationDescriptor descriptor = (OperationDescriptor) operationRegistry.getDescriptor(OperationDescriptor.class, name); if (descriptor == null) { System.out.println("Unknown operation '" + name + "'"); return; } String[][] resources = descriptor.getResources(Locale.getDefault()); String globalName = resources[0][1]; String description = resources[3][1]; String[] sourceNames = descriptor.getSourceNames(); Class[] sourceTypes = descriptor.getSourceClasses("rendered"); ParameterListDescriptor parameterListDescriptor = descriptor.getParameterListDescriptor("rendered"); String[] paramNames = parameterListDescriptor.getParamNames(); Class[] paramTypes = parameterListDescriptor.getParamClasses(); StringBuilder text = new StringBuilder(); text.append("Usage: "); text.append(globalName); text.append('('); StringBuilder paramListText = new StringBuilder(); if (sourceNames != null) { for (String sourceName : sourceNames) { if (paramListText.length() > 0) { paramListText.append(", "); } paramListText.append(sourceName); } } if (paramNames != null) { for (String paramName : paramNames) { if (paramListText.length() > 0) { paramListText.append(", "); } paramListText.append(paramName); Object defaultValue = parameterListDescriptor.getParamDefaultValue(paramName); if (defaultValue != ParameterListDescriptor.NO_PARAMETER_DEFAULT) { paramListText.append("="); paramListText.append(format(defaultValue)); } } } text.append(paramListText); text.append(')'); text.append('\n'); text.append("Description: "); text.append(description); text.append('\n'); text.append("Arguments:\n"); if (sourceNames != null) { for (int i = 0; i < sourceNames.length; i++) { String sourceName = sourceNames[i]; Class sourceType = sourceTypes[i]; text.append(" "); text.append(sourceName); text.append(": "); text.append("A source."); text.append(" (" + sourceType.getName() + ")"); text.append('\n'); } } if (paramNames != null) { for (int i = 0; i < paramNames.length; i++) { String paramName = paramNames[i]; Class paramType = paramTypes[i]; text.append(" "); text.append(paramName); text.append(": "); text.append(resources[6 + i][1]); text.append(" (" + paramType.getName() + ")"); text.append('\n'); } } System.out.println(text); } private static String format(Object value) { if (value == null) { return "null"; } Class<? extends Object> type = value.getClass(); if (type.isArray()) { StringBuilder builder = new StringBuilder(); builder.append('{'); int length = Array.getLength(value); for (int i = 0; i < length; i++) { if (i > 0) { builder.append(','); } builder.append(format(Array.get(value, i))); } builder.append('}'); return builder.toString(); } else if (EnumeratedParameter.class.isAssignableFrom(type)) { return ((EnumeratedParameter) value).getName(); } else if (Interpolation.class.isAssignableFrom(type)) { if (Interpolation.getInstance(Interpolation.INTERP_NEAREST).equals(value)) { return "INTERP_NEAREST"; } else if (Interpolation.getInstance(Interpolation.INTERP_BILINEAR).equals(value)) { return "INTERP_BILINEAR"; } else if (Interpolation.getInstance(Interpolation.INTERP_BICUBIC).equals(value)) { return "INTERP_BICUBIC"; } else if (Interpolation.getInstance(Interpolation.INTERP_BICUBIC_2).equals(value)) { return "INTERP_BICUBIC_2"; } } else if (CharSequence.class.isAssignableFrom(type)) { return "\"" + String.valueOf(value) + "\""; } return String.valueOf(value); } private static String spaces(int n) { char[] c = new char[n]; Arrays.fill(c, ' '); return new String(c); } }