ij.macro.Functions Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ij Show documentation
Show all versions of ij Show documentation
ImageJ is an open source Java image processing program inspired by NIH Image for the Macintosh.
package ij.macro;
import ij.*;
import ij.process.*;
import ij.gui.*;
import ij.measure.*;
import ij.plugin.*;
import ij.plugin.filter.*;
import ij.plugin.frame.*;
import ij.text.*;
import ij.io.*;
import ij.util.*;
import java.awt.*;
import java.awt.image.*;
import java.util.*;
import java.io.*;
import java.awt.event.KeyEvent;
import java.lang.reflect.*;
import java.net.URL;
import java.awt.datatransfer.*;
import java.awt.geom.*;
/** This class implements the built-in macro functions. */
public class Functions implements MacroConstants, Measurements {
Interpreter interp;
Program pgm;
boolean updateNeeded;
boolean autoUpdate = true;
ImageProcessor defaultIP;
ImagePlus defaultImp;
int imageType;
boolean fontSet;
Color globalColor;
double globalValue = Double.NaN;
int globalLineWidth;
Plot plot;
static int plotID;
int justification = ImageProcessor.LEFT_JUSTIFY;
Font font;
GenericDialog gd;
PrintWriter writer;
boolean altKeyDown, shiftKeyDown;
boolean antialiasedText;
StringBuffer buffer;
RoiManager roiManager;
Properties props;
CurveFitter fitter;
boolean showFitDialog;
boolean logFitResults;
boolean resultsPending;
Overlay offscreenOverlay;
Overlay overlayClipboard;
Roi roiClipboard;
GeneralPath overlayPath;
boolean overlayDrawLabels;
ResultsTable currentTable;
ResultsTable unUpdatedTable;
// save/restore settings
boolean saveSettingsCalled;
boolean usePointerCursor, hideProcessStackDialog;
float divideByZeroValue;
int jpegQuality;
int saveLineWidth;
boolean doScaling;
boolean weightedColor;
double[] weights;
boolean interpolateScaledImages, open100Percent, blackCanvas;
boolean useJFileChooser,debugMode;
Color foregroundColor, backgroundColor, roiColor;
boolean pointAutoMeasure, requireControlKey, useInvertingLut;
boolean disablePopup;
int measurements;
int decimalPlaces;
boolean blackBackground;
boolean autoContrast;
static WaitForUserDialog waitForUserDialog;
int pasteMode;
boolean expandableArrays;
int plotWidth;
int plotHeight;
int plotFontSize;
boolean plotInterpolate;
boolean plotNoGridLines;
boolean plotNoTicks;
boolean profileVerticalProfile;
boolean profileSubPixelResolution;
boolean waitForCompletion = true;
Functions(Interpreter interp, Program pgm) {
this.interp = interp;
this.pgm = pgm;
}
void doFunction(int type) {
switch (type) {
case RUN: doRun(); break;
case SELECT: IJ.selectWindow(getStringArg()); resetImage(); interp.selectCount++; break;
case WAIT: IJ.wait((int)getArg()); break;
case BEEP: interp.getParens(); IJ.beep(); break;
case RESET_MIN_MAX: interp.getParens(); IJ.resetMinAndMax(); resetImage(); break;
case RESET_THRESHOLD: interp.getParens(); IJ.resetThreshold(); resetImage(); break;
case PRINT: case WRITE: print(); break;
case DO_WAND: doWand(); break;
case SET_MIN_MAX: setMinAndMax(); break;
case SET_THRESHOLD: setThreshold(); break;
case SET_TOOL: setTool(); break;
case SET_FOREGROUND: setForegroundColor(); break;
case SET_BACKGROUND: setBackgroundColor(); break;
case SET_COLOR: setColor(); break;
case MAKE_LINE: makeLine(); break;
case MAKE_ARROW: makeArrow(); break;
case MAKE_OVAL: makeOval(); break;
case MAKE_RECTANGLE: makeRectangle(); break;
case MAKE_ROTATED_RECT: makeRotatedRectangle(); break;
case DUMP: interp.dump(); break;
case LINE_TO: lineTo(); break;
case MOVE_TO: moveTo(); break;
case DRAW_LINE: drawLine(); break;
case REQUIRES: requires(); break;
case AUTO_UPDATE: autoUpdate = getBooleanArg(); break;
case UPDATE_DISPLAY: interp.getParens(); updateDisplay(); break;
case DRAW_STRING: drawString(); break;
case SET_PASTE_MODE: IJ.setPasteMode(getStringArg()); break;
case DO_COMMAND: doCommand(); break;
case SHOW_STATUS: showStatus(); break;
case SHOW_PROGRESS: showProgress(); break;
case SHOW_MESSAGE: showMessage(false); break;
case SHOW_MESSAGE_WITH_CANCEL: showMessage(true); break;
case SET_PIXEL: case PUT_PIXEL: setPixel(); break;
case SNAPSHOT: case RESET: case FILL: doIPMethod(type); break;
case SET_LINE_WIDTH: setLineWidth((int)getArg()); break;
case CHANGE_VALUES: changeValues(); break;
case SELECT_IMAGE: selectImage(); break;
case EXIT: exit(); break;
case SET_LOCATION: setLocation(); break;
case GET_CURSOR_LOC: getCursorLoc(); break;
case GET_LINE: getLine(); break;
case GET_VOXEL_SIZE: getVoxelSize(); break;
case GET_HISTOGRAM: getHistogram(); break;
case GET_BOUNDING_RECT: case GET_BOUNDS: getBounds(); break;
case GET_LUT: getLut(); break;
case SET_LUT: setLut(); break;
case GET_COORDINATES: getCoordinates(); break;
case MAKE_SELECTION: makeSelection(); break;
case SET_RESULT: setResult(null); break;
case UPDATE_RESULTS: updateResults(); break;
case SET_BATCH_MODE: setBatchMode(); break;
case SET_JUSTIFICATION: setJustification(); break;
case SET_Z_COORDINATE: setZCoordinate(); break;
case GET_THRESHOLD: getThreshold(); break;
case GET_PIXEL_SIZE: getPixelSize(); break;
case SETUP_UNDO: interp.getParens(); Undo.setup(Undo.MACRO, getImage()); break;
case SAVE_SETTINGS: saveSettings(); break;
case RESTORE_SETTINGS: restoreSettings(); break;
case SET_KEY_DOWN: setKeyDown(); break;
case OPEN: open(); break;
case SET_FONT: setFont(); break;
case GET_MIN_AND_MAX: getMinAndMax(); break;
case CLOSE: close(); break;
case SET_SLICE: setSlice(); break;
case NEW_IMAGE: newImage(); break;
case SAVE: IJ.save(getStringArg()); break;
case SAVE_AS: saveAs(); break;
case SET_AUTO_THRESHOLD: setAutoThreshold(); break;
case RENAME: getImage().setTitle(getStringArg()); break;
case GET_STATISTICS: getStatistics(true); break;
case GET_RAW_STATISTICS: getStatistics(false); break;
case FLOOD_FILL: floodFill(); break;
case RESTORE_PREVIOUS_TOOL: restorePreviousTool(); break;
case SET_VOXEL_SIZE: setVoxelSize(); break;
case GET_LOCATION_AND_SIZE: getLocationAndSize(); break;
case GET_DATE_AND_TIME: getDateAndTime(); break;
case SET_METADATA: setMetadata(); break;
case CALCULATOR: imageCalculator(); break;
case SET_RGB_WEIGHTS: setRGBWeights(); break;
case MAKE_POLYGON: makePolygon(); break;
case SET_SELECTION_NAME: setSelectionName(); break;
case DRAW_RECT: case FILL_RECT: case DRAW_OVAL: case FILL_OVAL: drawOrFill(type); break;
case SET_OPTION: setOption(); break;
case SHOW_TEXT: showText(); break;
case SET_SELECTION_LOC: setSelectionLocation(); break;
case GET_DIMENSIONS: getDimensions(); break;
case WAIT_FOR_USER: waitForUser(); break;
case MAKE_POINT: makePoint(); break;
case MAKE_TEXT: makeText(); break;
case MAKE_ELLIPSE: makeEllipse(); break;
case GET_DISPLAYED_AREA: getDisplayedArea(); break;
case TO_SCALED: toScaled(); break;
case TO_UNSCALED: toUnscaled(); break;
}
}
final double getFunctionValue(int type) {
double value = 0.0;
switch (type) {
case GET_PIXEL: value = getPixel(); break;
case ABS: case COS: case EXP: case FLOOR: case LOG: case ROUND:
case SIN: case SQRT: case TAN: case ATAN: case ASIN: case ACOS:
value = math(type);
break;
case MATH: value = doMath(); break;
case MAX_OF: case MIN_OF: case POW: case ATAN2: value=math2(type); break;
case GET_TIME: interp.getParens(); value=System.currentTimeMillis(); break;
case GET_WIDTH: interp.getParens(); value=getImage().getWidth(); break;
case GET_HEIGHT: interp.getParens(); value=getImage().getHeight(); break;
case RANDOM: value=random(); break;
case GET_COUNT: case NRESULTS: value=getResultsCount(); break;
case GET_RESULT: value=getResult(null); break;
case GET_NUMBER: value=getNumber(); break;
case NIMAGES: value=getImageCount(); break;
case NSLICES: value=getStackSize(); break;
case LENGTH_OF: value=lengthOf(); break;
case GET_ID: interp.getParens(); value=getImage().getID(); break;
case BIT_DEPTH: interp.getParens(); value = getImage().getBitDepth(); break;
case SELECTION_TYPE: value=getSelectionType(); break;
case IS_OPEN: value=isOpen(); break;
case IS_ACTIVE: value=isActive(); break;
case INDEX_OF: value=indexOf(null); break;
case LAST_INDEX_OF: value=getFirstString().lastIndexOf(getLastString()); break;
case CHAR_CODE_AT: value=charCodeAt(); break;
case GET_BOOLEAN: value=getBoolean(); break;
case STARTS_WITH: case ENDS_WITH: value = startsWithEndsWith(type); break;
case IS_NAN: value = Double.isNaN(getArg())?1:0; break;
case GET_ZOOM: value = getZoom(); break;
case PARSE_FLOAT: value = parseDouble(getStringArg()); break;
case PARSE_INT: value = parseInt(); break;
case IS_KEY_DOWN: value = isKeyDown(); break;
case GET_SLICE_NUMBER: interp.getParens(); value=getImage().getCurrentSlice(); break;
case SCREEN_WIDTH: case SCREEN_HEIGHT: value = getScreenDimension(type); break;
case CALIBRATE: value = getImage().getCalibration().getCValue(getArg()); break;
case ROI_MANAGER: value = roiManager(); break;
case TOOL_ID: interp.getParens(); value = Toolbar.getToolId(); break;
case IS: value = is(); break;
case GET_VALUE: value = getValue(); break;
case STACK: value = doStack(); break;
case MATCHES: value = matches(null); break;
case GET_STRING_WIDTH: value = getStringWidth(); break;
case FIT: value = fit(); break;
case OVERLAY: value = overlay(); break;
case SELECTION_CONTAINS: value = selectionContains(); break;
case PLOT: value = doPlot(); break;
default:
interp.error("Numeric function expected");
}
return value;
}
String getStringFunction(int type) {
String str;
switch (type) {
case D2S: str = d2s(); break;
case TO_HEX: str = toString(16); break;
case TO_BINARY: str = toString(2); break;
case GET_TITLE: interp.getParens(); str=getImage().getTitle(); break;
case GET_STRING: str = getStringDialog(); break;
case SUBSTRING: str=substring(null); break;
case FROM_CHAR_CODE: str = fromCharCode(); break;
case GET_INFO: str = getInfo(); break;
case GET_IMAGE_INFO: interp.getParens(); str = getImageInfo(); break;
case GET_DIRECTORY: case GET_DIR: str = getDirectory(); break;
case GET_ARGUMENT: interp.getParens(); str=interp.argument!=null?interp.argument:""; break;
case TO_LOWER_CASE: str = getStringArg().toLowerCase(Locale.US); break;
case TO_UPPER_CASE: str = getStringArg().toUpperCase(Locale.US); break;
case RUN_MACRO: str = runMacro(false); break;
case EVAL: str = runMacro(true); break;
case TO_STRING: str = doToString(); break;
case REPLACE: str = replace(null); break;
case DIALOG: str = doDialog(); break;
case GET_METADATA: str = getMetadata(); break;
case FILE: str = doFile(); break;
case SELECTION_NAME: str = selectionName(); break;
case GET_VERSION: interp.getParens(); str = IJ.getVersion(); break;
case GET_RESULT_LABEL: str = getResultLabel(); break;
case CALL: str = call(); break;
case STRING: str = doString(); break;
case EXT: str = doExt(); break;
case EXEC: str = exec(); break;
case LIST: str = doList(); break;
case DEBUG: str = debug(); break;
case IJ_CALL: str = ijCall(); break;
case GET_RESULT_STRING: str = getResultString(null); break;
default:
str="";
interp.error("String function expected");
}
return str;
}
Variable[] getArrayFunction(int type) {
Variable[] array;
switch (type) {
case GET_PROFILE: array=getProfile(); break;
case NEW_ARRAY: array = newArray(); break;
case SPLIT: array = split(); break;
case GET_FILE_LIST: array = getFileList(); break;
case GET_FONT_LIST: array = getFontList(); break;
case NEW_MENU: array = newMenu(); break;
case GET_LIST: array = getList(); break;
case ARRAY_FUNC: array = doArray(); break;
default:
array = null;
interp.error("Array function expected");
}
return array;
}
// Type must be added to Interpreter.getExpressionType() and
// Interpreter.isString(), and functions returning a string must
// be added to isStringFunction().
Variable getVariableFunction(int type) {
Variable var = null;
switch (type) {
case TABLE: var = doTable(); break;
case ROI: var = doRoi(); break;
case ROI_MANAGER2: var = doRoiManager(); break;
case PROPERTY: var = doProperty(); break;
default:
interp.error("Variable function expected");
}
if (var==null)
var = new Variable(Double.NaN);
return var;
}
private void setLineWidth(int width) {
if (WindowManager.getCurrentImage()!=null) {
if (overlayPath!=null && width!=globalLineWidth)
addDrawingToOverlay(getImage());
getProcessor().setLineWidth(width);
}
globalLineWidth = width;
}
private double doMath() {
interp.getToken();
if (interp.token!='.')
interp.error("'.' expected");
interp.getToken();
if (!(interp.token==WORD||interp.token==NUMERIC_FUNCTION))
interp.error("Function name expected: ");
String name = interp.tokenString;
if (name.equals("min"))
return Math.min(getFirstArg(), getLastArg());
else if (name.equals("max"))
return Math.max(getFirstArg(), getLastArg());
else if (name.equals("pow"))
return Math.pow(getFirstArg(), getLastArg());
else if (name.equals("atan2"))
return Math.atan2(getFirstArg(), getLastArg());
double arg = getArg();
if (name.equals("ceil"))
return Math.ceil(arg);
else if (name.equals("abs"))
return Math.abs(arg);
else if (name.equals("cos"))
return Math.cos(arg);
else if (name.equals("exp"))
return Math.exp(arg);
else if (name.equals("floor"))
return Math.floor(arg);
else if (name.equals("log"))
return Math.log(arg);
else if (name.equals("log10"))
return Math.log10(arg);
else if (name.equals("round"))
return Math.round(arg);
else if (name.equals("sin"))
return Math.sin(arg);
else if (name.equals("sqr"))
return arg*arg;
else if (name.equals("sqrt"))
return Math.sqrt(arg);
else if (name.equals("tan"))
return Math.tan(arg);
else if (name.equals("atan"))
return Math.atan(arg);
else if (name.equals("asin"))
return Math.asin(arg);
else if (name.equals("acos"))
return Math.acos(arg);
else if (name.equals("erf"))
return IJMath.erf(arg);
else
interp.error("Unrecognized function name");
return Double.NaN;
}
final double math(int type) {
double arg = getArg();
switch (type) {
case ABS: return Math.abs(arg);
case COS: return Math.cos(arg);
case EXP: return Math.exp(arg);
case FLOOR: return Math.floor(arg);
case LOG: return Math.log(arg);
case ROUND: return Math.floor(arg + 0.5);
case SIN: return Math.sin(arg);
case SQRT: return Math.sqrt(arg);
case TAN: return Math.tan(arg);
case ATAN: return Math.atan(arg);
case ASIN: return Math.asin(arg);
case ACOS: return Math.acos(arg);
default: return 0.0;
}
}
final double math2(int type) {
double a1 = getFirstArg();
double a2 = getLastArg();
switch (type) {
case MIN_OF: return Math.min(a1, a2);
case MAX_OF: return Math.max(a1, a2);
case POW: return Math.pow(a1, a2);
case ATAN2: return Math.atan2(a1, a2);
default: return 0.0;
}
}
final String getString() {
String str = interp.getStringTerm();
while (true) {
interp.getToken();
if (interp.token=='+')
str += interp.getStringTerm();
else {
interp.putTokenBack();
break;
}
};
return str;
}
final boolean isStringFunction() {
Symbol symbol = pgm.table[interp.tokenAddress];
return symbol.type==D2S;
}
final double getArg() {
interp.getLeftParen();
double arg = interp.getExpression();
interp.getRightParen();
return arg;
}
final double getFirstArg() {
interp.getLeftParen();
return interp.getExpression();
}
final double getNextArg() {
interp.getComma();
return interp.getExpression();
}
final double getLastArg() {
interp.getComma();
double arg = interp.getExpression();
interp.getRightParen();
return arg;
}
String getStringArg() {
interp.getLeftParen();
String arg = getString();
interp.getRightParen();
return arg;
}
final String getFirstString() {
interp.getLeftParen();
return getString();
}
final String getNextString() {
interp.getComma();
return getString();
}
final String getLastString() {
interp.getComma();
String arg = getString();
interp.getRightParen();
return arg;
}
boolean getBooleanArg() {
interp.getLeftParen();
double arg = interp.getBooleanExpression();
interp.checkBoolean(arg);
interp.getRightParen();
return arg==0?false:true;
}
final Variable getVariableArg() {
interp.getLeftParen();
Variable v = getVariable();
interp.getRightParen();
return v;
}
final Variable getFirstVariable() {
interp.getLeftParen();
return getVariable();
}
final Variable getNextVariable() {
interp.getComma();
return getVariable();
}
final Variable getLastVariable() {
interp.getComma();
Variable v = getVariable();
interp.getRightParen();
return v;
}
final Variable getVariable() {
interp.getToken();
if (interp.token!=WORD)
interp.error("Variable expected");
Variable v = interp.lookupLocalVariable(interp.tokenAddress);
if (v==null)
v = interp.push(interp.tokenAddress, 0.0, null, interp);
Variable[] array = v.getArray();
if (array!=null) {
int index = interp.getIndex();
checkIndex(index, 0, v.getArraySize()-1);
v = array[index];
}
return v;
}
final Variable getFirstArrayVariable() {
interp.getLeftParen();
return getArrayVariable();
}
final Variable getNextArrayVariable() {
interp.getComma();
return getArrayVariable();
}
final Variable getLastArrayVariable() {
interp.getComma();
Variable v = getArrayVariable();
interp.getRightParen();
return v;
}
final Variable getArrayVariable() {
interp.getToken();
if (interp.token!=WORD)
interp.error("Variable expected");
Variable v = interp.lookupLocalVariable(interp.tokenAddress);
if (v==null)
v = interp.push(interp.tokenAddress, 0.0, null, interp);
return v;
}
final double[] getFirstArray() {
interp.getLeftParen();
return getNumericArray();
}
final double[] getNextArray() {
interp.getComma();
return getNumericArray();
}
final double[] getLastArray() {
interp.getComma();
double[] a = getNumericArray();
interp.getRightParen();
return a;
}
double[] getNumericArray() {
Variable[] a1 = getArray();
double[] a2 = new double[a1.length];
for (int i=0; iupper)
interp.error("Index ("+index+") is outside of the "+lower+"-"+upper+" range");
}
void doRun() {
interp.getLeftParen();
String arg1 = getString();
interp.getToken();
if (!(interp.token==')' || interp.token==','))
interp.error("',' or ')' expected");
String arg2 = null;
if (interp.token==',') {
arg2 = getString();
interp.getRightParen();
}
IJ.run(this.interp, arg1, arg2);
resetImage();
IJ.setKeyUp(IJ.ALL_KEYS);
shiftKeyDown = altKeyDown = false;
}
void setForegroundColor() {
boolean isImage = WindowManager.getCurrentImage()!=null;
int lnWidth = 0;
if (isImage)
lnWidth = getProcessor().getLineWidth();
int red=0, green=0, blue=0;
int arg1 = (int)getFirstArg();
if (interp.nextToken()==')') {
interp.getRightParen();
red = (arg1&0xff0000)>>16;
green = (arg1&0xff00)>>8;
blue = arg1&0xff;
} else {
red = arg1;
green = (int)getNextArg();
blue = (int)getLastArg();
}
IJ.setForegroundColor(red, green, blue);
resetImage();
if (isImage)
setLineWidth(lnWidth);
globalColor = null;
globalValue = Double.NaN;
}
void setBackgroundColor() {
int red=0, green=0, blue=0;
int arg1 = (int)getFirstArg();
if (interp.nextToken()==')') {
interp.getRightParen();
red = (arg1&0xff0000)>>16;
green = (arg1&0xff00)>>8;
blue = arg1&0xff;
} else {
red = arg1;
green = (int)getNextArg();
blue = (int)getLastArg();
}
IJ.setBackgroundColor(red, green, blue);
resetImage();
}
void setColor() {
interp.getLeftParen();
if (isStringArg()) {
globalColor = getColor();
globalValue = Double.NaN;
ImagePlus imp = WindowManager.getCurrentImage();
if (imp!=null) {
if (overlayPath!=null)
addDrawingToOverlay(imp);
getProcessor().setColor(globalColor);
}
interp.getRightParen();
return;
}
double arg1 = interp.getExpression();
if (interp.nextToken()==')') {
interp.getRightParen();
setColor(arg1);
return;
}
int red=(int)arg1, green=(int)getNextArg(), blue=(int)getLastArg();
if (red<0) red=0; if (green<0) green=0; if (blue<0) blue=0;
if (red>255) red=255; if (green>255) green=255; if (blue>255) blue=255;
globalColor = new Color(red, green, blue);
globalValue = Double.NaN;
if (WindowManager.getCurrentImage()!=null)
getProcessor().setColor(globalColor);
}
void setColor(double value) {
ImageProcessor ip = getProcessor();
ImagePlus imp = getImage();
switch (imp.getBitDepth()) {
case 8:
if (value<0 || value>255)
interp.error("Argument out of 8-bit range (0-255)");
ip.setValue(value);
break;
case 16:
if (imp.getLocalCalibration().isSigned16Bit())
value += 32768;
if (value<0 || value>65535)
interp.error("Argument out of 16-bit range (0-65535)");
ip.setValue(value);
break;
default:
ip.setValue(value);
break;
}
globalValue = value;
globalColor = null;
}
void makeLine() {
double x1d = getFirstArg();
double y1d = getNextArg();
double x2d = getNextArg();
interp.getComma();
double y2d = interp.getExpression();
interp.getToken();
if (interp.token==')')
IJ.makeLine(x1d, y1d, x2d, y2d);
else {
Polygon points = new Polygon();
points.addPoint((int)Math.round(x1d),(int)Math.round(y1d));
points.addPoint((int)Math.round(x2d),(int)Math.round(y2d));
while (interp.token==',') {
int x = (int)Math.round(interp.getExpression());
if (points.npoints==2 && interp.nextToken()==')') {
interp.getRightParen();
Roi line = new Line(x1d, y1d, x2d, y2d);
line.updateWideLine((float)x);
getImage().setRoi(line);
return;
}
interp.getComma();
int y = (int)Math.round(interp.getExpression());
points.addPoint(x,y);
interp.getToken();
}
getImage().setRoi(new PolygonRoi(points, Roi.POLYLINE));
}
resetImage();
}
void makeArrow() {
String options = "";
double x1 = getFirstArg();
double y1 = getNextArg();
double x2 = getNextArg();
double y2 = getNextArg();
if (interp.nextToken()==',')
options = getNextString();
interp.getRightParen();
Arrow arrow = new Arrow(x1, y1, x2, y2);
arrow.setStyle(options);
getImage().setRoi(arrow);
}
void makeOval() {
Roi previousRoi = getImage().getRoi();
if (shiftKeyDown||altKeyDown) getImage().saveRoi();
IJ.makeOval(getFirstArg(), getNextArg(), getNextArg(), getLastArg());
Roi roi = getImage().getRoi();
if (previousRoi!=null && roi!=null)
updateRoi(roi);
resetImage();
shiftKeyDown = altKeyDown = false;
IJ.setKeyUp(IJ.ALL_KEYS);
}
void makeRectangle() {
Roi previousRoi = getImage().getRoi();
if (shiftKeyDown||altKeyDown) getImage().saveRoi();
double x = getFirstArg();
double y = getNextArg();
double w = getNextArg();
double h = getNextArg();
int arcSize = 0;
if (interp.nextToken()==',') {
interp.getComma();
arcSize = (int)interp.getExpression();
}
interp.getRightParen();
if (arcSize<1)
IJ.makeRectangle(x, y, w, h);
else {
ImagePlus imp = getImage();
imp.setRoi(new Roi(x,y,w,h,arcSize));
}
Roi roi = getImage().getRoi();
if (previousRoi!=null && roi!=null)
updateRoi(roi);
resetImage();
shiftKeyDown = altKeyDown = false;
IJ.setKeyUp(IJ.ALL_KEYS);
}
void makeRotatedRectangle() {
getImage().setRoi(new RotatedRectRoi(getFirstArg(), getNextArg(), getNextArg(), getNextArg(), getLastArg()));
resetImage();
}
ImagePlus getImage() {
ImagePlus imp = IJ.getImage(interp);
if (imp.getWindow()==null && IJ.getInstance()!=null && !interp.isBatchMode() && WindowManager.getTempCurrentImage()==null)
throw new RuntimeException(Macro.MACRO_CANCELED);
defaultIP = null;
defaultImp = imp;
return imp;
}
void resetImage() {
defaultImp = null;
defaultIP = null;
fontSet = false;
}
ImageProcessor getProcessor() {
if (defaultIP==null) {
defaultIP = getImage().getProcessor();
if (globalLineWidth>0)
defaultIP.setLineWidth(globalLineWidth);
if (globalColor!=null)
defaultIP.setColor(globalColor);
else if (!Double.isNaN(globalValue))
defaultIP.setValue(globalValue);
else
defaultIP.setColor(Toolbar.getForegroundColor());
}
return defaultIP;
}
int getType() {
imageType = getImage().getType();
return imageType;
}
void setPixel() {
interp.getLeftParen();
int a1 = (int)interp.getExpression();
interp.getComma();
double a2 = interp.getExpression();
interp.getToken();
ImageProcessor ip = getProcessor();
if (interp.token==',') {
double a3 = interp.getExpression();
interp.getRightParen();
if (ip instanceof FloatProcessor)
ip.putPixelValue(a1, (int)a2, a3);
else
ip.putPixel(a1, (int)a2, (int)a3);
} else {
if (interp.token!=')') interp.error("')' expected");
if (ip instanceof ColorProcessor)
ip.set(a1, (int)a2);
else
ip.setf(a1, (float)a2);
}
updateNeeded = true;
}
double getPixel() {
interp.getLeftParen();
double a1 = interp.getExpression();
ImageProcessor ip = getProcessor();
double value = 0.0;
interp.getToken();
if (interp.token==',') {
double a2 = interp.getExpression();
interp.getRightParen();
int ia1 = (int)a1;
int ia2 = (int)a2;
if (a1==ia1 && a2==ia2) {
if (ip instanceof FloatProcessor)
value = ip.getPixelValue(ia1, ia2);
else
value = ip.getPixel(ia1, ia2);
} else {
if (ip instanceof ColorProcessor)
value = ip.getPixelInterpolated(a1, a2);
else {
ImagePlus imp = getImage();
Calibration cal = imp.getCalibration();
imp.setCalibration(null);
ip = imp.getProcessor();
value = ip.getInterpolatedValue(a1, a2);
imp.setCalibration(cal);
}
}
} else {
if (interp.token!=')') interp.error("')' expected");
if (ip instanceof ColorProcessor)
value = ip.get((int)a1);
else
value = ip.getf((int)a1);
}
return value;
}
void setZCoordinate() {
int z = (int)getArg();
int n = z + 1;
ImagePlus imp = getImage();
ImageStack stack = imp.getStack();
int size = stack.size();
if (z<0 || z>=size)
interp.error("Z coordinate ("+z+") is out of 0-"+(size-1)+ " range");
this.defaultIP = stack.getProcessor(n);
}
void moveTo() {
interp.getLeftParen();
int a1 = (int)Math.round(interp.getExpression());
interp.getComma();
int a2 = (int)Math.round(interp.getExpression());
interp.getRightParen();
getProcessor().moveTo(a1, a2);
}
void lineTo() {
interp.getLeftParen();
int a1 = (int)Math.round(interp.getExpression());
interp.getComma();
int a2 = (int)Math.round(interp.getExpression());
interp.getRightParen();
ImageProcessor ip = getProcessor();
ip.lineTo(a1, a2);
updateAndDraw();
}
void drawLine() {
interp.getLeftParen();
int x1 = (int)Math.round(interp.getExpression());
interp.getComma();
int y1 = (int)Math.round(interp.getExpression());
interp.getComma();
int x2 = (int)Math.round(interp.getExpression());
interp.getComma();
int y2 = (int)Math.round(interp.getExpression());
interp.getRightParen();
ImageProcessor ip = getProcessor();
ip.drawLine(x1, y1, x2, y2);
updateAndDraw();
}
void doIPMethod(int type) {
interp.getParens();
ImageProcessor ip = getProcessor();
switch (type) {
case SNAPSHOT: ip.snapshot(); break;
case RESET:
ip.reset();
updateNeeded = true;
break;
case FILL:
ImagePlus imp = getImage();
Roi roi = imp.getRoi();
if (roi==null) {
ip.resetRoi();
ip.fill();
} else {
ip.setRoi(roi);
ip.fill(ip.getMask());
}
imp.updateAndDraw();
break;
}
}
void updateAndDraw() {
if (autoUpdate) {
ImagePlus imp = defaultImp;
if (imp==null)
imp = getImage();
imp.updateChannelAndDraw();
imp.changes = true;
} else
updateNeeded = true;
}
void updateDisplay() {
if (updateNeeded && WindowManager.getImageCount()>0) {
ImagePlus imp = getImage();
imp.updateAndDraw();
updateNeeded = false;
}
}
void drawString() {
interp.getLeftParen();
String str = getString();
interp.getComma();
int x = (int)(interp.getExpression()+0.5);
interp.getComma();
int y = (int)(interp.getExpression()+0.5);
Color background = null;
if (interp.nextToken()==',') {
interp.getComma();
background = getColor();
}
interp.getRightParen();
ImageProcessor ip = getProcessor();
setFont(ip);
ip.setJustification(justification);
ip.setAntialiasedText(antialiasedText);
if (background!=null)
ip.drawString(str, x, y, background);
else
ip.drawString(str, x, y);
updateAndDraw();
}
void setFont(ImageProcessor ip) {
if (font!=null && !fontSet)
ip.setFont(font);
fontSet = true;
}
void setJustification() {
String str = getStringArg().toLowerCase(Locale.US);
int just = ImageProcessor.LEFT_JUSTIFY;
if (str.equals("center"))
just = ImageProcessor.CENTER_JUSTIFY;
else if (str.equals("right"))
just = ImageProcessor.RIGHT_JUSTIFY;
justification = just;
}
void changeValues() {
double darg1 = getFirstArg();
double darg2 = getNextArg();
double darg3 = getLastArg();
ImagePlus imp = getImage();
ImageProcessor ip = getProcessor();
Roi roi = imp.getRoi();
ImageProcessor mask = null;
if (roi==null || !roi.isArea()) {
ip.resetRoi();
roi = null;
} else {
ip.setRoi(roi);
mask = ip.getMask();
if (mask!=null) ip.snapshot();
}
int xmin=0, ymin=0, xmax=imp.getWidth(), ymax=imp.getHeight();
if (roi!=null) {
Rectangle r = roi.getBounds();
xmin=r.x; ymin=r.y; xmax=r.x+r.width; ymax=r.y+r.height;
}
boolean isFloat = getType()==ImagePlus.GRAY32;
if (imp.getBitDepth()==24) {
darg1 = (int)darg1&0xffffff;
darg2 = (int)darg2&0xffffff;
}
double v;
for (int y=ymin; y=darg1 && v<=darg2;
if (Double.isNaN(darg1) && Double.isNaN(darg2) && Double.isNaN(v))
replace = true;
if (replace) {
if (isFloat)
ip.putPixelValue(x, y, darg3);
else
ip.putPixel(x, y, (int)darg3);
}
}
}
if (mask!=null) ip.reset(mask);
imp.updateAndDraw();
updateNeeded = false;
}
void requires() {
if (IJ.versionLessThan(getStringArg()))
interp.done = true;
}
Random ran;
double random() {
double dseed = Double.NaN;
boolean gaussian = false;
if (interp.nextToken()=='(') {
interp.getLeftParen();
if (isStringArg()) {
String arg = getString().toLowerCase(Locale.US);
if (arg.equals("seed")) {
interp.getComma();
dseed = interp.getExpression();
long seed = (long)dseed;
if (seed!=dseed)
interp.error("Seed not integer");
ran = new Random(seed);
ImageProcessor.setRandomSeed(seed);
} else if (arg.equals("gaussian"))
gaussian = true;
else
interp.error("'seed' or ''gaussian' expected");
}
interp.getRightParen();
if (!Double.isNaN(dseed)) return Double.NaN;
}
ImageProcessor.setRandomSeed(Double.NaN);
interp.getParens();
if (ran==null)
ran = new Random();
if (gaussian)
return ran.nextGaussian();
else
return ran.nextDouble();
}
double getResult(ResultsTable rt) {
interp.getLeftParen();
String column = getString();
int row = -1;
if (interp.nextToken()==',') {
interp.getComma();
row = (int)interp.getExpression();
}
if (interp.nextToken()==',') {
interp.getComma();
String title = getString();
rt = getResultsTable(title);
}
if (rt==null)
rt = getResultsTable(true);
interp.getRightParen();
int counter = rt.size();
if (row==-1) row = counter-1;
if (row<0 || row>=counter)
interp.error("Row ("+row+") out of range");
int col = rt.getColumnIndex(column);
if (!rt.columnExists(col))
return Double.NaN;
else {
double value = rt.getValueAsDouble(col, row);
if (Double.isNaN(value)) {
String s = rt.getStringValue(col, row);
if (s!=null && !s.equals("NaN"))
value = Tools.parseDouble(s);
}
return value;
}
}
String getResultString(ResultsTable rt) {
interp.getLeftParen();
String column = getString();
int row = -1;
if (interp.nextToken()==',') {
interp.getComma();
row = (int)interp.getExpression();
}
if (interp.nextToken()==',') {
interp.getComma();
String title = getString();
rt = getResultsTable(title);
}
interp.getRightParen();
if (rt==null)
rt = getResultsTable(true);
int counter = rt.size();
if (row==-1) row = counter-1;
if (row<0 || row>=counter)
interp.error("Row ("+row+") out of range");
int col = rt.getColumnIndex(column);
if (rt.columnExists(col))
return rt.getStringValue(col, row);
else {
String label = null;
if ("Label".equals(column))
label = rt.getLabel(row);
return label!=null?label:"null";
}
}
String getResultLabel() {
int row = (int)getArg();
ResultsTable rt = getResultsTable(true);
int counter = rt.size();
if (row<0 || row>=counter)
interp.error("Row ("+row+") out of range");
String label = rt.getLabel(row);
if (label!=null)
return label;
else {
label = rt.getStringValue("Label", row);
return label!=null?label:"";
}
}
private ResultsTable getResultsTable(boolean reportErrors) {
ResultsTable rt = Analyzer.getResultsTable();
int size = rt.size();
if (size==0) {
Frame frame = WindowManager.getFrontWindow();
if (frame==null || (frame instanceof Editor))
frame = WindowManager.getFrame("Results");
if (frame!=null && (frame instanceof TextWindow)) {
TextPanel tp = ((TextWindow)frame).getTextPanel();
rt = tp.getOrCreateResultsTable();
size = rt!=null?rt.size():0;
}
}
if (size==0) {
Window win = WindowManager.getActiveTable();
if (win!=null && (win instanceof TextWindow)) {
TextPanel tp = ((TextWindow)win).getTextPanel();
rt = tp.getOrCreateResultsTable();
size = rt!=null?rt.size():0;
}
}
if (size==0 && reportErrors)
interp.error("No results found");
return rt;
}
void setResult(ResultsTable rt) {
interp.getLeftParen();
String column = getString();
interp.getComma();
int row = (int)interp.getExpression();
interp.getComma();
double value = 0.0;
String stringValue = null;
boolean isLabel = column.equals("Label");
if (isStringArg() || isLabel)
stringValue = getString();
else
value = interp.getExpression();
if (interp.nextToken()==',') {
interp.getComma();
String title = getString();
rt = getResultsTable(title);
}
interp.getRightParen();
if (rt==null) {
rt = Analyzer.getResultsTable();
resultsPending = true;
} else
unUpdatedTable = rt;
if (row<0 || row>rt.size())
interp.error("Row ("+row+") out of range");
if (row==rt.size())
rt.incrementCounter();
try {
if (stringValue!=null) {
if (isLabel)
rt.setLabel(stringValue, row);
else
rt.setValue(column, row, stringValue);
} else
rt.setValue(column, row, value);
} catch (Exception e) {
interp.error(""+e.getMessage());
}
}
void updateResults() {
interp.getParens();
ResultsTable rt = Analyzer.getResultsTable();
rt.show("Results");
resultsPending = false;
}
double getNumber() {
String prompt = getFirstString();
double defaultValue = getLastArg();
String title = interp.macroName!=null?interp.macroName:"";
if (title.endsWith(" Options"))
title = title.substring(0, title.length()-8);
GenericDialog gd = new GenericDialog(title);
int decimalPlaces = (int)defaultValue==defaultValue?0:2;
gd.addNumericField(prompt, defaultValue, decimalPlaces);
gd.showDialog();
if (gd.wasCanceled()) {
interp.done = true;
return defaultValue;
}
double v = gd.getNextNumber();
if (gd.invalidNumber())
return defaultValue;
else
return v;
}
double getBoolean() {
interp.getLeftParen();
String prompt = getString();
String yesButton = " Yes ";
String noButton = " No ";
if (interp.nextToken()==',') {
yesButton = getNextString();
noButton = getNextString();
}
interp.getRightParen();
String title = interp.macroName!=null?interp.macroName:"";
if (title.endsWith(" Options"))
title = title.substring(0, title.length()-8);
YesNoCancelDialog d = new YesNoCancelDialog(IJ.getInstance(), title, prompt, yesButton, noButton);
if (d.cancelPressed()) {
interp.done = true;
return 0.0;
} else if (d.yesPressed())
return 1.0;
else
return 0.0;
}
String getStringDialog() {
interp.getLeftParen();
String prompt = getString();
interp.getComma();
String defaultStr = getString();
interp.getRightParen();
String title = interp.macroName!=null?interp.macroName:"";
if (title.endsWith(" Options"))
title = title.substring(0, title.length()-8);
GenericDialog gd = new GenericDialog(title);
gd.addStringField(prompt, defaultStr, 20);
gd.showDialog();
String str = "";
if (gd.wasCanceled())
interp.done = true;
else
str = gd.getNextString();
return str;
}
String d2s() {
return IJ.d2s(getFirstArg(), (int)getLastArg());
}
String toString(int base) {
int arg = (int)getArg();
if (base==2)
return Integer.toBinaryString(arg);
else
return Integer.toHexString(arg);
}
double getStackSize() {
interp.getParens();
return getImage().getStackSize();
}
double getImageCount() {
interp.getParens();
return WindowManager.getImageCount();
}
double getResultsCount() {
interp.getParens();
return Analyzer.getResultsTable().getCounter();
}
void getCoordinates() {
Variable xCoordinates = getFirstArrayVariable();
Variable yCoordinates = getLastArrayVariable();
ImagePlus imp = getImage();
Roi roi = imp.getRoi();
if (roi==null)
interp.error("Selection required");
Variable[] xa, ya;
if (roi.getType()==Roi.LINE) {
xa = new Variable[2];
ya = new Variable[2];
Line line = (Line)roi;
xa[0] = new Variable(line.x1d);
ya[0] = new Variable(line.y1d);
xa[1] = new Variable(line.x2d);
ya[1] = new Variable(line.y2d);
} else {
FloatPolygon fp = roi.getFloatPolygon();
if (fp!=null) {
xa = new Variable[fp.npoints];
ya = new Variable[fp.npoints];
for (int i=0; i0 && s2!=null && (s2.equals(",")||s2.equals(";")))
strings = s1.split(s2,-1);
else if (s1.length()>0 && s2!=null && s2.length()>=3 && s2.startsWith("(")&&s2.endsWith(")")) {
s2 = s2.substring(1,s2.length()-1);
strings = s1.split(s2,-1);
} else
strings = (s2==null||s2.equals(""))?Tools.split(s1):Tools.split(s1, s2);
Variable[] array = new Variable[strings.length];
for (int i=0; i0) {
String[] list2 = new String[n];
int j = 0;
for (int i=0; i65535)
interp.error("Value (" + value + ") out of 0-65535 range");
chars[count++] = (char)value;
if (interp.nextToken()==',')
interp.getToken();
}
interp.getRightParen();
return new String(chars, 0, count);
}
String getInfo() {
if (interp.nextNextToken()==STRING_CONSTANT
|| (interp.nextToken()=='('&&interp.nextNextToken()!=')'))
return getInfo(getStringArg());
else {
interp.getParens();
return getWindowContents();
}
}
String getInfo(String key) {
String lowercaseKey = key.toLowerCase(Locale.US);
int len = lowercaseKey.length();
if (lowercaseKey.equals("command.name")) {
return ImageJ.getCommandName();
} else if (lowercaseKey.equals("overlay")) {
Overlay overlay = getImage().getOverlay();
if (overlay==null)
return "";
else
return overlay.toString();
} else if (lowercaseKey.equals("log")) {
String log = IJ.getLog();
return log!=null?log:"";
} else if (key.indexOf(".")==-1) {
ImagePlus imp = getImage();
String value = imp.getStringProperty(key);
if (value!=null) return value;
} else if (lowercaseKey.equals("micrometer.abbreviation")) {
return "\u00B5m";
} else if (lowercaseKey.equals("image.title")) {
return getImage().getTitle();
} else if (lowercaseKey.equals("image.subtitle")) {
ImagePlus imp = getImage();
ImageWindow win = imp.getWindow();
return win!=null?win.createSubtitle():"";
} else if (lowercaseKey.equals("slice.label")) {
ImagePlus imp = getImage();
String label = null;
if (imp.getStackSize()==1)
label = (String)imp.getProperty("Label");
else
label = imp.getStack().getShortSliceLabel(imp.getCurrentSlice());
return label!=null?label:"";
} else if (lowercaseKey.equals("window.contents")) {
return getWindowContents();
} else if (lowercaseKey.equals("image.description")) {
String description = "";
FileInfo fi = getImage().getOriginalFileInfo();
if (fi!=null) description = fi.description;
if (description==null) description = "";
return description;
} else if (lowercaseKey.equals("image.filename")) {
String name= "";
FileInfo fi = getImage().getOriginalFileInfo();
if (fi!=null && fi.fileName!=null) name= fi.fileName;
return name;
} else if (lowercaseKey.equals("image.directory")) {
String dir= "";
FileInfo fi = getImage().getOriginalFileInfo();
if (fi!=null && fi.directory!=null) dir= fi.directory;
return dir;
} else if (lowercaseKey.equals("selection.name")||lowercaseKey.equals("roi.name")) {
ImagePlus imp = getImage();
Roi roi = imp.getRoi();
String name = roi!=null?roi.getName():null;
return name!=null?name:"";
} else if (lowercaseKey.equals("selection.color")||lowercaseKey.equals("roi.color")) {
ImagePlus imp = getImage();
Roi roi = imp.getRoi();
if (roi==null)
interp.error("No selection");
Color color = roi.getStrokeColor();
return Colors.colorToString(color);
} else if (lowercaseKey.equals("font.name")) {
resetImage();
ImageProcessor ip = getProcessor();
setFont(ip);
return ip.getFont().getName();
} else if (lowercaseKey.equals("threshold.method")) {
return ThresholdAdjuster.getMethod();
} else if (lowercaseKey.equals("threshold.mode")) {
return ThresholdAdjuster.getMode();
} else if (lowercaseKey.equals("window.type")) {
return getWindowType();
} else if (lowercaseKey.equals("window.title")||lowercaseKey.equals("window.name")) {
return getWindowTitle();
} else if (lowercaseKey.equals("macro.filepath")) {
String path = Macro_Runner.getFilePath();
return path!=null?path:"null";
} else {
String value = "";
try {
value = System.getProperty(key);
} catch (Exception e) {};
if (value==null)
return("Invalid key");
else
return value;
}
return "";
}
private String getWindowTitle() {
Window win = WindowManager.getActiveWindow();
if (IJ.debugMode) IJ.log("getWindowTitle: "+win);
if (win==null)
return "";
else if (win instanceof Frame)
return ((Frame)win).getTitle();
else if (win instanceof Dialog)
return ((Dialog)win).getTitle();
else
return "";
}
private String getWindowType() {
Window win = WindowManager.getActiveWindow();
if (win==null)
return "";
String type = win.getClass().getName();
if (win instanceof TextWindow) {
TextPanel tp = ((TextWindow)win).getTextPanel();
if (tp.getColumnHeadings().isEmpty() && tp.getResultsTable()==null)
type = "Text";
else {
if (tp.getResultsTable()!=null)
type = "ResultsTable";
else
type = "Table";
}
} else if (type.equals("ij.gui.PlotWindow"))
type = "Plot";
else if (type.equals("ij.gui.HistogramWindow"))
type = "Histogram";
else if (win instanceof ij.gui.ImageWindow)
type = "Image";
else {
if (type.contains(".")) //strip off hierarchy
type = type.substring(type.lastIndexOf('.')+1);
}
return type;
}
String getWindowContents() {
Frame frame = WindowManager.getFrontWindow();
if (frame!=null && frame instanceof TextWindow) {
TextPanel tp = ((TextWindow)frame).getTextPanel();
return tp.getText();
} else if (frame!=null && frame instanceof Editor) {
return ((Editor)frame).getText();
} else if (frame!=null && frame instanceof Recorder) {
return ((Recorder)frame).getText();
} else
return getImageInfo();
}
String getImageInfo() {
ImagePlus imp = getImage();
ImageInfo infoPlugin = new ImageInfo();
return infoPlugin.getImageInfo(imp);
}
public String getDirectory() {
String dir = IJ.getDirectory(getStringArg());
if (dir==null) dir = "";
return dir;
}
double getSelectionType() {
interp.getParens();
double type = -1;
if (WindowManager.getImageCount()==0)
return type;
ImagePlus imp = getImage();
Roi roi = imp.getRoi();
if (roi!=null)
type = roi.getType();
return type;
}
void showMessage(boolean withCancel) {
String message;
interp.getLeftParen();
String title = getString();
if (interp.nextToken()==',') {
interp.getComma();
message = getString();
} else {
message = title;
title = "";
}
interp.getRightParen();
if (withCancel)
IJ.showMessageWithCancel(title, message);
else
IJ.showMessage(title, message);
}
double lengthOf() {
int length = 0;
interp.getLeftParen();
switch (interp.nextToken()) {
case STRING_CONSTANT:
case STRING_FUNCTION:
case USER_FUNCTION:
length = getString().length();
break;
case WORD:
if (pgm.code[interp.pc+2]=='[') {
length = getString().length();
break;
}
interp.getToken();
Variable v = interp.lookupVariable();
if (v==null) return 0.0;
String s = v.getString();
if (s!=null)
length = s.length();
else {
Variable[] array = v.getArray();
if (array!=null)
length = v.getArraySize();
else
interp.error("String or array expected");
}
break;
default:
interp.error("String or array expected");
}
interp.getRightParen();
return length;
}
void getCursorLoc() {
Variable x = getFirstVariable();
Variable y = getNextVariable();
Variable z = getNextVariable();
Variable flags = getLastVariable();
ImagePlus imp = getImage();
ImageCanvas ic = imp.getCanvas();
if (ic==null) return;
Point p = ic.getCursorLoc();
x.setValue(p.x);
y.setValue(p.y);
z.setValue(imp.getCurrentSlice()-1);
Roi roi = imp.getRoi();
flags.setValue(ic.getModifiers()+((roi!=null)&&roi.contains(p.x,p.y)?32:0));
}
void getLine() {
Variable vx1 = getFirstVariable();
Variable vy1 = getNextVariable();
Variable vx2 = getNextVariable();
Variable vy2 = getNextVariable();
Variable lineWidth = getLastVariable();
ImagePlus imp = getImage();
double x1=-1, y1=-1, x2=-1, y2=-1;
Roi roi = imp.getRoi();
if (roi!=null && roi.getType()==Roi.LINE) {
Line line = (Line)roi;
x1=line.x1d; y1=line.y1d; x2=line.x2d; y2=line.y2d;
}
vx1.setValue(x1);
vy1.setValue(y1);
vx2.setValue(x2);
vy2.setValue(y2);
lineWidth.setValue(roi!=null?roi.getStrokeWidth():1);
}
void getVoxelSize() {
Variable width = getFirstVariable();
Variable height = getNextVariable();
Variable depth = getNextVariable();
Variable unit = getLastVariable();
ImagePlus imp = getImage();
Calibration cal = imp.getCalibration();
width.setValue(cal.pixelWidth);
height.setValue(cal.pixelHeight);
depth.setValue(cal.pixelDepth);
unit.setString(cal.getUnits());
}
void getHistogram() {
interp.getLeftParen();
Variable values = null;
if (interp.nextToken()==NUMBER)
interp.getExpression();
else
values = getArrayVariable();
Variable counts = getNextArrayVariable();
interp.getComma();
int nBins = (int)interp.getExpression();
ImagePlus imp = getImage();
double histMin=0.0, histMax=0.0;
boolean setMinMax = false;
int bitDepth = imp.getBitDepth();
if (interp.nextToken()==',') {
histMin = getNextArg();
histMax = getLastArg();
if (bitDepth==8 || bitDepth==24)
interp.error("16 or 32-bit image required to set histMin and histMax");
setMinMax = true;
} else
interp.getRightParen();
if (nBins==65536 && bitDepth==16) {
Variable[] array = counts.getArray();
ImageProcessor ip = imp.getProcessor();
Roi roi = imp.getRoi();
if (roi!=null)
ip.setRoi(roi);
int[] hist = ip.getHistogram();
if (array!=null && array.length==nBins) {
for (int i=0; ix.length || n>y.length)
interp.error("Array too short");
} else {
interp.getRightParen();
if (y.length!=n)
interp.error("Arrays are not the same length");
}
ImagePlus imp = getImage();
boolean floatCoordinates = false;
for (int i=0; i=currentPlot.getNumPlotObjects())
interp.error("Index out of bounds");
currentPlot.setStyle(index, getLastString());
if (plot == null)
currentPlot.updateImage();
return Double.NaN;
} else if (name.equals("makeHighResolution")) {
return makeHighResolution(currentPlot);
} else if (name.equals("setColor")) {
return setPlotColor(currentPlot);
} else if (name.equals("setBackgroundColor")) {
return setPlotBackgroundColor(currentPlot);
} else if (name.equals("setFontSize")) {
return setPlotFontSize(currentPlot, false);
} else if (name.equals("setAxisLabelSize")) {
return setPlotFontSize(currentPlot, true);
} else if (name.equals("setXYLabels")) {
currentPlot.setXYLabels(getFirstString(), getLastString());
currentPlot.updateImage();
return Double.NaN;
} else if (name.equals("setFormatFlags")) {
return setPlotFormatFlags(currentPlot);
} else if (name.equals("useTemplate")) {
return fromPlot(currentPlot, 't');
} else if (name.equals("setOptions")) {
return setPlotOptions(currentPlot);
} else if (name.equals("addFromPlot")) {
return fromPlot(currentPlot, 'a');
} else if (name.equals("getFrameBounds")) {
return getPlotFrameBounds(currentPlot);
} else if (name.equals("objectCount")||name.equals("getNumObjects")) {
return currentPlot.getNumPlotObjects();
} else if (name.equals("add")) {
return addToPlot(currentPlot);
} else if (name.equals("replace")) {
return replacePlot(currentPlot);
} else if (name.equals("addText") || name.equals("drawLabel")) {
return addPlotText(currentPlot);
}
// the following commands need a plot under construction
if (plot==null)
interp.error("No plot defined");
if (name.equals("show")) {
return showPlot();
} else if (name.equals("update")) {
return updatePlot();
} else if (name.equals("drawLine")) {
return drawPlotLine(false);
} else if (name.equals("drawNormalizedLine")) {
return drawPlotLine(true);
} else if (name.equals("drawVectors")) {
return drawPlotVectors();
} else if (name.equals("drawShapes")) {
return drawShapes();
} else if (name.equals("drawGrid")) {
plot.drawShapes("redraw_grid", null);
return Double.NaN;
} else if (name.startsWith("setLineWidth")) {
plot.setLineWidth((float)getArg());
return Double.NaN;
} else if (name.startsWith("setJustification")) {
setJustification();
return Double.NaN;
} else if (name.equals("addHistogram")) {
interp.getLeftParen();
Variable[] arrV = getArray();
interp.getComma();
double binWidth = interp.getExpression();
double binCenter = 0;
interp.getToken();
if (interp.token == ',')
binCenter = interp.getExpression();
else
interp.putTokenBack();
interp.getRightParen();
int len1 = arrV.length;
double[] arrD = new double[len1];
for (int i=0; i= 2 boxes
}
nBoxes = arr.length;
if (jj > 0 && arr2D[0].length != nBoxes) {
interp.error("Arrays must have same length (" + nBoxes + ")");
return Double.NaN;
}
if (arr2D == null) {
arr2D = new double[nCoords][nBoxes];
}
for (int boxNo = 0; boxNo < nBoxes; boxNo++) {
arr2D[jj][boxNo] = arr[boxNo];
}
}
}
interp.getRightParen();
float[][] floatArr = new float[nCoords][nBoxes];
for (int row = 0; row < nCoords; row++) {
floatArr[row] = Tools.toFloat(arr2D[row]);
}
ArrayList shapeData = new ArrayList();
for (int box = 0; box < nBoxes; box++) {
float[] coords = new float[nCoords];
for (int coord = 0; coord < nCoords; coord++) {
coords[coord] = (float) (arr2D[coord][box]);
}
shapeData.add(coords);
}
plot.drawShapes(type, shapeData);
return Double.NaN;
}
double setPlotColor(Plot plot) {
interp.getLeftParen();
Color color = getColor();
Color color2 = null;
if (interp.nextToken()!=')') {
interp.getComma();
color2 = getColor();
}
plot.setColor(color, color2);
interp.getRightParen();
return Double.NaN;
}
double setPlotBackgroundColor(Plot plot) {
interp.getLeftParen();
Color color = getColor();
interp.getRightParen();
plot.setBackgroundColor(color);
return Double.NaN;
}
double setPlotFontSize(Plot plot, boolean forAxisLabels) {
float size = (float)getFirstArg();
int style = -1;
if (interp.nextToken()!=')') {
String options = getNextString().toLowerCase();
style = 0;
if (options.indexOf("bold") >= 0)
style |= Font.BOLD;
if (options.indexOf("ital") >= 0)
style |= Font.ITALIC;
}
interp.getRightParen();
if (forAxisLabels)
plot.setAxisLabelFont(style, size);
else
plot.setFont(style, size);
plot.updateImage();
return Double.NaN;
}
double setPlotFormatFlags(Plot plot) {
String flagString = getStringArg();
try {
int flags = Integer.parseInt(flagString, 2);
plot.setFormatFlags(flags);
plot.updateImage();
} catch (NumberFormatException e) {
interp.error("Plot format flags not binary");
}
return Double.NaN;
}
/** Plot.useTemplate with 't', Plot.addFromPlot with 'a' */
double fromPlot(Plot plot, char type) {
ImagePlus sourceImp = null;
interp.getLeftParen();
if (isStringArg()) {
String title = getString();
sourceImp = WindowManager.getImage(title);
if (sourceImp==null)
interp.error("Image \""+title+"\" not found");
} else {
int id = (int)interp.getExpression();
sourceImp = WindowManager.getImage(id);
if (sourceImp==null)
interp.error("Image ID="+id+" not found");
}
Plot sourcePlot = (Plot)(sourceImp.getProperty(Plot.PROPERTY_KEY));
if (sourcePlot==null)
interp.error("No plot: "+sourceImp.getTitle());
if (type == 'a') {
int objectIndex = (int)getNextArg();
if (objectIndex < 0 || objectIndex > plot.getNumPlotObjects())
interp.error("Plot "+sourceImp.getTitle()+" has "+plot.getNumPlotObjects()+"items, no number "+objectIndex);
plot.addObjectFromPlot(sourcePlot, objectIndex);
plot.updateImage();
} else
plot.useTemplate(sourcePlot);
interp.getRightParen();
return Double.NaN;
}
double addPlotLegend(Plot plot) {
String labels = getFirstString();
String options = "auto";
if (interp.nextToken()!=')')
options = getLastString();
else
interp.getRightParen();
plot.setColor(Color.BLACK);
plot.setLineWidth(1);
plot.addLegend(labels, options);
return Double.NaN;
}
double getPlotLimits(Plot plot) {
double[] limits = plot.getLimits();
getFirstVariable().setValue(limits[0]); //xMin
getNextVariable().setValue(limits[1]); //xMax
getNextVariable().setValue(limits[2]); //yMin
getLastVariable().setValue(limits[3]); //yMax
return Double.NaN;
}
double getPlotFrameBounds(Plot plot) {
Rectangle r = plot.getDrawingFrame();
getFirstVariable().setValue(r.x);
getNextVariable().setValue(r.y);
getNextVariable().setValue(r.width);
getLastVariable().setValue(r.height);
return Double.NaN;
}
double makeHighResolution(Plot plot) {
String title = getFirstString();
double scale = getNextArg();
boolean antialiasedText = true;
if (interp.nextToken()!=')') {
String options = getLastString().toLowerCase();
if (options.indexOf("disable")!=-1)
antialiasedText = false;
} else
interp.getRightParen();
plot.makeHighResolution(title, (float)scale, antialiasedText, true);
return Double.NaN;
}
double addToPlot(Plot currentPlot) {
String shape = getFirstString();
int what = Plot.toShape(shape);
double[] x = getNextArray();
double[] y;
double[] errorBars = null;
String label = null;
if (interp.nextToken()==')') {
y = x;
x = new double[y.length];
for (int i=0; iindex2)
interp.error("beginIndex>endIndex");
checkIndex(index1, 0, s.length());
checkIndex(index2, 0, s.length());
return s.substring(index1, index2);
}
private String getStringFunctionArg(String s) {
if (s==null) {
s=getFirstString();
interp.getComma();
} else
interp.getLeftParen();
return s;
}
int indexOf(String s1) {
s1 = getStringFunctionArg(s1);
String s2 = getString();
int fromIndex = 0;
if (interp.nextToken()==',') {
fromIndex = (int)getLastArg();
checkIndex(fromIndex, 0, s1.length()-1);
} else
interp.getRightParen();
if (fromIndex==0)
return s1.indexOf(s2);
else
return s1.indexOf(s2, fromIndex);
}
int startsWithEndsWith(int type) {
String s1 = getFirstString();
String s2 = getLastString();
if (type==STARTS_WITH)
return s1.startsWith(s2)?1:0;
else
return s1.endsWith(s2)?1:0;
}
double isActive() {
int id = (int)getArg();
ImagePlus imp = WindowManager.getCurrentImage();
if (imp==null || imp.getID()!=id)
return 0.0; //false
else
return 1.0; //true
}
double isOpen() {
interp.getLeftParen();
if (isStringArg()) {
String title = getString();
interp.getRightParen();
return isOpen(title)?1.0:0.0;
} else {
int id = (int)interp.getExpression();
interp.getRightParen();
return WindowManager.getImage(id)==null?0.0:1.0;
}
}
boolean isOpen(String title) {
boolean open = WindowManager.getWindow(title)!=null;
if (open)
return true;
else if (Interpreter.isBatchMode() && Interpreter.imageTable!=null) {
for (Enumeration en=Interpreter.imageTable.elements(); en.hasMoreElements();) {
ImagePlus imp = (ImagePlus)en.nextElement();
if (imp!=null && imp.getTitle().equals(title))
return true;
}
}
return false;
}
boolean isStringArg() {
int nextToken = pgm.code[interp.pc+1];
int tok = nextToken&0xff;
if (tok==STRING_CONSTANT||tok==STRING_FUNCTION) return true;
if (tok==VARIABLE_FUNCTION && interp.isString(interp.pc+1)) return true;
if (tok!=WORD) return false;
Variable v = interp.lookupVariable(nextToken>>TOK_SHIFT);
if (v==null) return false;
int type = v.getType();
if (type!=Variable.ARRAY)
return v.getType()==Variable.STRING;
Variable[] array = v.getArray();
if (array.length==0 || interp.nextNextToken()=='.') return false;
return array[0].getType()==Variable.STRING;
}
void exit() {
String msg = null;
if (interp.nextToken()=='(') {
interp.getLeftParen();
if (isStringArg())
msg = getString();
interp.getRightParen();
}
interp.finishUp();
if (msg!=null)
IJ.showMessage("Macro", msg);
throw new RuntimeException(Macro.MACRO_CANCELED);
}
private void showStatus () {
String s = getStringArg();
boolean withSign = s.startsWith("!");
if (withSign)
s = s.substring(1);
IJ.protectStatusBar(false);
IJ.showStatus(s);
IJ.protectStatusBar(withSign);
interp.statusUpdated = true;
}
void showProgress() {
ImageJ ij = IJ.getInstance();
ij.gui.ProgressBar progressBar = ij!=null?ij.getProgressBar():null;
interp.getLeftParen();
double arg1 = interp.getExpression();
if (interp.nextToken()==',') {
interp.getComma();
double arg2 = interp.getExpression();
if (progressBar!=null) progressBar.show((arg1+1.0)/arg2, true);
} else
if (progressBar!=null) progressBar.show(arg1, true);
interp.getRightParen();
interp.showingProgress = true;
}
void saveSettings() {
interp.getParens();
usePointerCursor = Prefs.usePointerCursor;
hideProcessStackDialog = IJ.hideProcessStackDialog;
divideByZeroValue = FloatBlitter.divideByZeroValue;
jpegQuality = FileSaver.getJpegQuality();
saveLineWidth = Line.getWidth();
doScaling = ImageConverter.getDoScaling();
weightedColor = Prefs.weightedColor;
weights = ColorProcessor.getWeightingFactors();
interpolateScaledImages = Prefs.interpolateScaledImages;
open100Percent = Prefs.open100Percent;
blackCanvas = Prefs.blackCanvas;
useJFileChooser = Prefs.useJFileChooser;
debugMode = IJ.debugMode;
foregroundColor =Toolbar.getForegroundColor();
backgroundColor =Toolbar.getBackgroundColor();
roiColor = Roi.getColor();
pointAutoMeasure = Prefs.pointAutoMeasure;
requireControlKey = Prefs.requireControlKey;
useInvertingLut = Prefs.useInvertingLut;
saveSettingsCalled = true;
measurements = Analyzer.getMeasurements();
decimalPlaces = Analyzer.getPrecision();
blackBackground = Prefs.blackBackground;
autoContrast = Prefs.autoContrast;
pasteMode = Roi.getCurrentPasteMode();
plotWidth = PlotWindow.plotWidth;
plotHeight = PlotWindow.plotHeight;
plotFontSize = PlotWindow.fontSize;
plotInterpolate = PlotWindow.interpolate;
plotNoGridLines = PlotWindow.noGridLines;
plotNoTicks = PlotWindow.noTicks;
profileVerticalProfile = Prefs.verticalProfile;
profileSubPixelResolution = Prefs.subPixelResolution;
}
void restoreSettings() {
interp.getParens();
if (!saveSettingsCalled)
interp.error("saveSettings() not called");
Prefs.usePointerCursor = usePointerCursor;
IJ.hideProcessStackDialog = hideProcessStackDialog;
FloatBlitter.divideByZeroValue = divideByZeroValue;
FileSaver.setJpegQuality(jpegQuality);
Line.setWidth(saveLineWidth);
ImageConverter.setDoScaling(doScaling);
if (weightedColor!=Prefs.weightedColor) {
ColorProcessor.setWeightingFactors(weights[0], weights[1], weights[2]);
Prefs.weightedColor = !(weights[0]==1d/3d && weights[1]==1d/3d && weights[2]==1d/3d);
}
Prefs.interpolateScaledImages = interpolateScaledImages;
Prefs.open100Percent = open100Percent;
Prefs.blackCanvas = blackCanvas;
Prefs.useJFileChooser = useJFileChooser;
Prefs.useInvertingLut = useInvertingLut;
IJ.setDebugMode(debugMode);
Toolbar.setForegroundColor(foregroundColor);
Toolbar.setBackgroundColor(backgroundColor);
Roi.setColor(roiColor);
Analyzer.setMeasurements(measurements);
Analyzer.setPrecision(decimalPlaces);
ColorProcessor.setWeightingFactors(weights[0], weights[1], weights[2]);
Prefs.blackBackground = blackBackground;
Prefs.autoContrast = autoContrast;
Roi.setPasteMode(pasteMode);
PlotWindow.plotWidth = plotWidth;
PlotWindow.plotHeight = plotHeight;
PlotWindow.fontSize = plotFontSize;
PlotWindow.interpolate = plotInterpolate;
PlotWindow.noGridLines = plotNoGridLines;
PlotWindow.noTicks = plotNoTicks;
Prefs.verticalProfile = profileVerticalProfile;
Prefs.subPixelResolution = profileSubPixelResolution;
}
void setKeyDown() {
String keys = getStringArg();
keys = keys.toLowerCase(Locale.US);
altKeyDown = keys.indexOf("alt")!=-1;
if (altKeyDown)
IJ.setKeyDown(KeyEvent.VK_ALT);
else
IJ.setKeyUp(KeyEvent.VK_ALT);
shiftKeyDown = keys.indexOf("shift")!=-1;
if (shiftKeyDown)
IJ.setKeyDown(KeyEvent.VK_SHIFT);
else
IJ.setKeyUp(KeyEvent.VK_SHIFT);
boolean controlKeyDown = keys.indexOf("control")!=-1;
if (controlKeyDown)
IJ.setKeyDown(KeyEvent.VK_CONTROL);
else
IJ.setKeyUp(KeyEvent.VK_CONTROL);
if (keys.equals("space"))
IJ.setKeyDown(KeyEvent.VK_SPACE);
else
IJ.setKeyUp(KeyEvent.VK_SPACE);
if (keys.indexOf("esc")!=-1)
abortPluginOrMacro();
else
interp.keysSet = true;
}
void abortPluginOrMacro() {
Interpreter.abortPrevious();
IJ.setKeyDown(KeyEvent.VK_ESCAPE);
ImagePlus imp = WindowManager.getCurrentImage();
if (imp!=null) {
ImageWindow win = imp.getWindow();
if (win!=null) {
win.running = false;
win.running2 = false;
}
}
}
void open() {
File f = null;
interp.getLeftParen();
if (interp.nextToken()==')') {
interp.getRightParen();
IJ.open();
} else {
double n = Double.NaN;
String options = null;
String path = getString();
f = new File(path);
if (interp.nextToken()==',') {
interp.getComma();
if (isStringArg())
options = getString();
else
n = interp.getExpression();
}
interp.getRightParen();
if (!Double.isNaN(n)) {
try {
IJ.open(path, (int)n);
} catch (Exception e) {
String msg = e.getMessage();
if (msg!=null&&msg.indexOf("canceled")==-1)
interp.error(""+msg);
}
} else {
if (f!=null&&f.isDirectory()) {
FolderOpener fo = new FolderOpener();
if (options!=null && options.contains("virtual"))
fo.openAsVirtualStack(true);
ImagePlus imp = fo.openFolder(path);
if (imp!=null) imp.show();
} else
IJ.open(path);
}
if (path!=null&&!path.equals("")&&f!=null) {
OpenDialog.setLastDirectory(f.getParent()+File.separator);
OpenDialog.setLastName(f.getName());
}
}
resetImage();
}
double roiManager() {
String cmd = getFirstString();
cmd = cmd.toLowerCase();
String path = null;
String color = null;
double lineWidth = 1.0;
int index=0;
double dx=0.0, dy=0.0;
double countOrIndex=Double.NaN;
boolean twoArgCommand = cmd.equals("open")||cmd.equals("save")||cmd.equals("rename")
||cmd.equals("set color")||cmd.equals("set fill color")||cmd.equals("set line width")
||cmd.equals("associate")||cmd.equals("centered")||cmd.equals("usenames")
||cmd.equals("save selected");
boolean select = cmd.equals("select");
boolean multiSelect = false;
boolean add = cmd.equals("add");
if (twoArgCommand)
path = getLastString();
else if (add) {
if (interp.nextToken()==',') {
interp.getComma();
color = interp.getString();
}
if (interp.nextToken()==',') {
interp.getComma();
lineWidth = interp.getExpression();
}
interp.getRightParen();
} else if (select) {
interp.getComma();
multiSelect = isArrayArg();
if (!multiSelect) {
index = (int)interp.getExpression();
interp.getRightParen();
}
} else if (cmd.equals("translate")) {
dx = getNextArg();
dy = getLastArg();
} else
interp.getRightParen();
if (RoiManager.getInstance()==null&&roiManager==null) {
if (Interpreter.isBatchMode())
roiManager = new RoiManager(true);
else
IJ.run("ROI Manager...");
}
RoiManager rm = roiManager!=null?roiManager:RoiManager.getInstance();
if (rm==null)
interp.error("ROI Manager not found");
if (multiSelect)
return setMultipleIndexes(rm);
if (twoArgCommand)
rm.runCommand(cmd, path);
else if (add)
rm.runCommand("Add", color, lineWidth);
else if (select) {
int n = rm.getCount();
checkIndex(index, 0, n-1);
if (shiftKeyDown || altKeyDown) {
rm.select(index, shiftKeyDown, altKeyDown);
shiftKeyDown = altKeyDown = false;
} else
rm.select(index);
} else if (cmd.equals("count"))
countOrIndex = rm.getCount();
else if (cmd.equals("index"))
countOrIndex = rm.getSelectedIndex();
else if (cmd.equals("translate")) {
rm.translate(dx, dy);
return Double.NaN;
} else {
if (!rm.runCommand(cmd))
interp.error("Invalid ROI Manager command");
}
return countOrIndex;
}
boolean isArrayArg() {
int nextToken = pgm.code[interp.pc+1];
int tok = nextToken&0xff;
if (tok==ARRAY_FUNCTION) return true;
if (tok!=WORD) return false;
Variable v = interp.lookupVariable(nextToken>>TOK_SHIFT);
if (v==null) return false;
int nextNextToken = pgm.code[interp.pc+2];
return v.getType()==Variable.ARRAY && nextNextToken!='[';
}
double setMultipleIndexes(RoiManager rm) {
if (interp.nextToken()==',')
interp.getComma();
double[] indexes = getNumericArray();
interp.getRightParen();
int[] selectedIndexes = new int[indexes.length];
int count = rm.getCount();
for (int i=0; i=count)
interp.error("Invalid index: "+selectedIndexes[i]);
}
rm.setSelectedIndexes(selectedIndexes);
return Double.NaN;
}
void setFont() {
String name = getFirstString();
int size = 0;
int style = 0;
if (name.equals("user")) {
name = TextRoi.getDefaultFontName();
size = TextRoi.getDefaultFontSize();
style = TextRoi.getDefaultFontStyle();
antialiasedText = TextRoi.isAntialiased();
interp.getRightParen();
} else {
size = (int)getNextArg();
antialiasedText = false;
if (interp.nextToken()==',') {
String styles = getLastString().toLowerCase();
if (styles.indexOf("bold")!=-1) style += Font.BOLD;
if (styles.indexOf("italic")!=-1) style += Font.ITALIC;
if (styles.indexOf("anti")!=-1) antialiasedText = true;
} else
interp.getRightParen();
}
font = new Font(name, style, size);
fontSet = false;
}
void getMinAndMax() {
Variable min = getFirstVariable();
Variable max = getLastVariable();
ImagePlus imp = getImage();
double v1 = imp.getDisplayRangeMin();
double v2 = imp.getDisplayRangeMax();
Calibration cal = imp.getCalibration();
v1 = cal.getCValue(v1);
v2 = cal.getCValue(v2);
min.setValue(v1);
max.setValue(v2);
}
void selectImage() {
interp.getLeftParen();
if (isStringArg()) {
String title = getString();
if (!isOpen(title))
interp.error("\""+title+"\" not found");
selectImage(title);
interp.getRightParen();
} else {
int id = (int)interp.getExpression();
if (WindowManager.getImage(id)==null)
interp.error("Image "+id+" not found");
IJ.selectWindow(id);
interp.getRightParen();
}
resetImage();
interp.selectCount++;
}
void selectImage(String title) {
if (Interpreter.isBatchMode()) {
if (Interpreter.imageTable!=null) {
for (Enumeration en=Interpreter.imageTable.elements(); en.hasMoreElements();) {
ImagePlus imp = (ImagePlus)en.nextElement();
if (imp!=null) {
if (imp.getTitle().equals(title)) {
ImagePlus imp2 = WindowManager.getCurrentImage();
if (imp2!=null && imp2!=imp) imp2.saveRoi();
WindowManager.setTempCurrentImage(imp);
Interpreter.activateImage(imp);
return;
}
}
}
}
selectWindowManagerImage(title);
} else
selectWindowManagerImage(title);
}
void notFound(String title) {
interp.error(title+" not found");
}
void selectWindowManagerImage(String title) {
long start = System.currentTimeMillis();
while (System.currentTimeMillis()-start<4000) { // 4 sec timeout
int[] wList = WindowManager.getIDList();
int len = wList!=null?wList.length:0;
for (int i=0; inSlices)
interp.error("Argument must be >=1 and <="+nSlices);
else {
if (imp.isHyperStack())
imp.setPosition(n);
else
imp.setSlice(n);
}
resetImage();
}
void newImage() {
String title = getFirstString();
String type = getNextString();
int width = (int)getNextArg();
int height = (int)getNextArg();
int depth = (int)getNextArg();
int c=-1, z=-1, t=-1;
if (interp.nextToken()==')')
interp.getRightParen();
else {
c = depth;
z = (int)getNextArg();
t = (int)getLastArg();
}
if (width<1 || height<1)
interp.error("Width or height < 1");
if (c<0)
IJ.newImage(title, type, width, height, depth);
else {
ImagePlus imp = IJ.createImage(title, type, width, height, c, z, t);
imp.show();
}
resetImage();
}
void saveAs() {
String format = getFirstString();
String path = null;
boolean oneArg = false;
if (interp.nextToken()==',')
path = getLastString();
else {
interp.getRightParen();
oneArg = true;
}
if (oneArg && (format.contains(File.separator)||format.contains("/")))
IJ.save(format); // assume argument is a path
else
IJ.saveAs(format, path);
}
double getZoom() {
interp.getParens();
ImagePlus imp = getImage();
ImageCanvas ic = imp.getCanvas();
if (ic==null)
{interp.error("Image not displayed"); return 0.0;}
else
return ic.getMagnification();
}
void setAutoThreshold() {
String mString = null;
if (interp.nextToken()=='(') {
interp.getLeftParen();
if (isStringArg())
mString = getString();
interp.getRightParen();
}
ImagePlus img = getImage();
ImageProcessor ip = getProcessor();
if (ip instanceof ColorProcessor)
interp.error("Non-RGB image expected");
ip.setRoi(img.getRoi());
if (mString!=null) {
try {
if (mString.indexOf("stack")!=-1)
IJ.setAutoThreshold(img, mString);
else
ip.setAutoThreshold(mString);
} catch (Exception e) {
interp.error(""+e.getMessage());
}
} else
ip.setAutoThreshold(ImageProcessor.ISODATA2, ImageProcessor.RED_LUT);
img.updateAndDraw();
resetImage();
}
double parseDouble(String s) {
if (s==null) return 0.0;
s = s.trim();
if (s.indexOf(' ')!=-1) s = s.substring(0, s.indexOf(' '));
return Tools.parseDouble(s);
}
double parseInt() {
String s = getFirstString();
int radix = 10;
if (interp.nextToken()==',') {
interp.getComma();
radix = (int)interp.getExpression();
if (radix<2||radix>36) radix = 10;
}
interp.getRightParen();
double n;
try {
if (radix==10) {
n = parseDouble(s);
if (!Double.isNaN(n)) n = Math.round(n);
} else
n = Integer.parseInt(s, radix);
} catch (NumberFormatException e) {
n = Double.NaN;
}
return n;
}
void print() {
interp.inPrint = true;
String s = getFirstString();
if (interp.nextToken()==',') {
if (s.startsWith("[") && s.endsWith("]")) {
printToWindow(s);
return;
} else if (s.equals("~0~")) {
if (writer==null)
interp.error("File not open");
String s2 = getLastString();
if (s2.endsWith("\n"))
writer.print(s2);
else
writer.println(s2);
interp.inPrint = false;
return;
}
StringBuffer sb = new StringBuffer(s);
do {
sb.append(" ");
sb.append(getNextString());
} while (interp.nextToken()==',');
s = sb.toString();
}
interp.getRightParen();
interp.log(s);
interp.inPrint = false;
}
void printToWindow(String s) {
String title = s.substring(1, s.length()-1);
String s2 = getLastString();
boolean isCommand = s2.startsWith("\\");
Frame frame = WindowManager.getFrame(title);
if (frame==null) {
if (isCommand) {
interp.done = true;
return;
} else
interp.error("Window not found");
}
boolean isEditor = frame instanceof Editor;
if (!(isEditor || frame instanceof TextWindow))
interp.error("Window is not text window");
if (isEditor) {
Editor ed = (Editor)frame;
ed.setIsMacroWindow(true);
if (isCommand)
handleEditorCommand(ed, s2);
else
ed.append(s2);
} else {
TextWindow tw = (TextWindow)frame;
if (isCommand)
handleTextWindowCommand(tw, s2);
else {
tw.append(s2);
TextPanel tp = tw.getTextPanel();
if (tp!=null) tp.setResultsTable(null);
}
}
}
void handleEditorCommand(Editor ed, String s) {
if (s.startsWith("\\Update:")) {
TextArea ta = ed.getTextArea();
ta.setText(s.substring(8, s.length()));
ta.setEditable(false);
} else if (s.equals("\\Close"))
ed.close();
else
ed.append(s);
}
void handleTextWindowCommand(TextWindow tw, String s) {
TextPanel tp = tw.getTextPanel();
if (s.startsWith("\\Update:")) {
int n = tp.getLineCount();
String s2 = s.substring(8, s.length());
if (n==0)
tp.append(s2);
else
tp.setLine(n-1, s2);
} else if (s.startsWith("\\Update")) {
int cindex = s.indexOf(":");
if (cindex==-1)
{tp.append(s); return;}
String nstr = s.substring(7, cindex);
int line = (int)Tools.parseDouble(nstr, -1);
if (line<0) interp.error("Row index<0 or NaN");
int count = tp.getLineCount();
while (line>=count) {
tp.append("");
count++;
}
String s2 = s.substring(cindex+1, s.length());
tp.setLine(line, s2);
} else if (s.equals("\\Clear"))
tp.clear();
else if (s.equals("\\Close"))
tw.close();
else if (s.startsWith("\\Headings:"))
tp.setColumnHeadings(s.substring(10));
else
tp.append(s);
}
double isKeyDown() {
double value = 0.0;
String key = getStringArg().toLowerCase(Locale.US);
if (key.indexOf("alt")!=-1) value = IJ.altKeyDown()==true?1.0:0.0;
else if (key.indexOf("shift")!=-1) value = IJ.shiftKeyDown()==true?1.0:0.0;
else if (key.indexOf("space")!=-1) value = IJ.spaceBarDown()==true?1.0:0.0;
else if (key.indexOf("control")!=-1) value = IJ.controlKeyDown()==true?1.0:0.0;
else interp.error("Invalid key");
return value;
}
String runMacro(boolean eval) {
interp.getLeftParen();
String name = getString();
String arg = null;
if (interp.nextToken()==',') {
interp.getComma();
arg = getString();
}
interp.getRightParen();
if (eval) {
if (arg!=null && (name.equals("script")||name.equals("js")))
return (new Macro_Runner()).runJavaScript(arg, "");
else if (arg!=null && (name.equals("bsh")))
return Macro_Runner.runBeanShell(arg,"");
else if (arg!=null && (name.equals("python")))
return Macro_Runner.runPython(arg,"");
else
return IJ.runMacro(name, arg);
} else
return IJ.runMacroFile(name, arg);
}
void setThreshold() {
double lower = getFirstArg();
double upper = getNextArg();
String mode = null;
if (interp.nextToken()==',') {
interp.getComma();
mode = getString();
}
interp.getRightParen();
IJ.setThreshold(lower, upper, mode);
resetImage();
}
void drawOrFill(int type) {
int x = (int)getFirstArg();
int y = (int)getNextArg();
int width = (int)getNextArg();
int height = (int)getLastArg();
ImageProcessor ip = getProcessor();
switch (type) {
case DRAW_RECT: ip.drawRect(x, y, width, height); break;
case FILL_RECT: ip.setRoi(x, y, width, height); ip.fill(); break;
case DRAW_OVAL: ip.drawOval(x, y, width, height); break;
case FILL_OVAL: ip.fillOval(x, y, width, height); break;
}
updateAndDraw();
}
double getScreenDimension(int type) {
interp.getParens();
Dimension screen = IJ.getScreenSize();
if (type==SCREEN_WIDTH)
return screen.width;
else
return screen.height;
}
void getStatistics(boolean calibrated) {
Variable count = getFirstVariable();
Variable mean=null, min=null, max=null, std=null, hist=null;
int params = AREA+MEAN+MIN_MAX;
interp.getToken();
int arg = 1;
while (interp.token==',') {
arg++;
switch (arg) {
case 2: mean = getVariable(); break;
case 3: min = getVariable(); break;
case 4: max = getVariable(); break;
case 5: std = getVariable(); params += STD_DEV; break;
case 6: hist = getArrayVariable(); break;
default: interp.error("')' expected");
}
interp.getToken();
}
if (interp.token!=')') interp.error("')' expected");
ImagePlus imp = getImage();
Calibration cal = calibrated?imp.getCalibration():null;
ImageProcessor ip = getProcessor();
ImageStatistics stats = null;
Roi roi = imp.getRoi();
int lineWidth = Line.getWidth();
if (roi!=null && roi.isLine() && lineWidth>1) {
ImageProcessor ip2;
if (roi.getType()==Roi.LINE) {
ip2 = ip;
Rectangle saveR = ip2.getRoi();
ip2.setRoi(roi.getPolygon());
stats = ImageStatistics.getStatistics(ip2, params, cal);
ip2.setRoi(saveR);
} else {
ip2 = (new Straightener()).straightenLine(imp, lineWidth);
stats = ImageStatistics.getStatistics(ip2, params, cal);
}
} else if (roi!=null && roi.isLine()) {
ProfilePlot profile = new ProfilePlot(imp);
double[] values = profile.getProfile();
ImageProcessor ip2 = new FloatProcessor(values.length, 1, values);
if (roi instanceof Line) {
Line l = (Line)roi;
if ((l.y1==l.y2||l.x1==l.x2)&&l.x1==l.x1d&& l.y1==l.y1d&& l.x2==l.x2d&& l.y2==l.y2d)
ip2.setRoi(0, 0, ip2.getWidth()-1, 1);
}
stats = ImageStatistics.getStatistics(ip2, params, cal);
} else {
ip.setRoi(roi);
stats = ImageStatistics.getStatistics(ip, params, cal);
}
if (calibrated)
count.setValue(stats.area);
else
count.setValue(stats.pixelCount);
if (mean!=null) mean.setValue(stats.mean);
if (min!=null) min.setValue(stats.min);
if (max!=null) max.setValue(stats.max);
if (std!=null) std.setValue(stats.stdDev);
if (hist!=null) {
boolean is16bit = !calibrated && ip instanceof ShortProcessor && stats.histogram16!=null;
int[] histogram = is16bit?stats.histogram16:stats.histogram;
int bins = is16bit?(int)(stats.max+1):histogram.length;
Variable[] array = new Variable[bins];
int hmax = is16bit?(int)stats.max:255;
for (int i=0; i<=hmax; i++)
array[i] = new Variable(histogram[i]);
hist.setArray(array);
}
}
String replace(String s1) {
s1 = getStringFunctionArg(s1);
String s2 = getString();
String s3 = getLastString();
if (s2.length()==1) {
StringBuilder sb = new StringBuilder(s1.length());
for (int i=0; i1?"label":"info";
}
String metadata = null;
if (type.contains("info")) {
metadata = (String)imp.getProperty("Info");
if (metadata==null && imp.getStackSize()>1)
metadata = imp.getStack().getSliceLabel(imp.getCurrentSlice());
} else
metadata = imp.getStack().getSliceLabel(imp.getCurrentSlice());
if (metadata==null)
metadata = "";
return metadata;
}
ImagePlus getImageArg() {
ImagePlus img = null;
if (isStringArg()) {
String title = getString();
img = WindowManager.getImage(title);
} else {
int id = (int)interp.getExpression();
img = WindowManager.getImage(id);
}
if (img==null) interp.error("Image not found");
return img;
}
void imageCalculator() {
String operator = getFirstString();
interp.getComma();
ImagePlus img1 = getImageArg();
interp.getComma();
ImagePlus img2 = getImageArg();
interp.getRightParen();
ImageCalculator ic = new ImageCalculator();
ic.calculate(operator, img1, img2);
resetImage();
}
void setRGBWeights() {
double r = getFirstArg();
double g = getNextArg();
double b = getLastArg();
if (interp.rgbWeights==null)
interp.rgbWeights = ColorProcessor.getWeightingFactors();
ColorProcessor.setWeightingFactors(r, g, b);
}
private void makePolygon() {
Polygon points = new Polygon();
points.addPoint((int)Math.round(getFirstArg()), (int)Math.round(getNextArg()));
interp.getToken();
while (interp.token==',') {
int x = (int)Math.round(interp.getExpression());
interp.getComma();
int y = (int)Math.round(interp.getExpression());
points.addPoint(x,y);
interp.getToken();
}
if (points.npoints<3)
interp.error("Fewer than 3 points");
ImagePlus imp = getImage();
Roi previousRoi = imp.getRoi();
if (shiftKeyDown||altKeyDown) imp.saveRoi();
imp.setRoi(new PolygonRoi(points, Roi.POLYGON));
Roi roi = imp.getRoi();
if (previousRoi!=null && roi!=null)
updateRoi(roi);
resetImage();
shiftKeyDown = altKeyDown = false;
}
void updateRoi(Roi roi) {
if (shiftKeyDown || altKeyDown)
roi.update(shiftKeyDown, altKeyDown);
shiftKeyDown = altKeyDown = false;
}
String doFile() {
interp.getToken();
if (interp.token!='.')
interp.error("'.' expected");
interp.getToken();
if (!(interp.token==WORD || interp.token==STRING_FUNCTION || interp.token==NUMERIC_FUNCTION || interp.token==PREDEFINED_FUNCTION))
interp.error("Function name expected: ");
String name = interp.tokenString;
if (name.equals("open"))
return openFile();
else if (name.equals("openAsString"))
return openAsString();
else if (name.equals("openAsRawString"))
return openAsRawString();
else if (name.equals("openUrlAsString"))
return IJ.openUrlAsString(getStringArg());
else if (name.equals("openDialog"))
return openDialog();
else if (name.equals("close"))
return closeFile();
else if (name.equals("separator")) {
interp.getParens();
return File.separator;
} else if (name.equals("directory")) {
interp.getParens();
String lastDir = OpenDialog.getLastDirectory();
return lastDir!=null?lastDir:"";
} else if (name.equals("name")) {
interp.getParens();
String lastName = OpenDialog.getLastName();
return lastName!=null?lastName:"";
} else if (name.equals("nameWithoutExtension")) {
interp.getParens();
return nameWithoutExtension();
} else if (name.equals("rename")) {
File f1 = new File(getFirstString());
File f2 = new File(getLastString());
if (checkPath(f1) && checkPath(f2))
return f1.renameTo(f2)?"1":"0";
else
return "0";
} else if (name.equals("copy")) {
String f1 = getFirstString();
String f2 = getLastString();
String err = Tools.copyFile(f1, f2);
if (err.length()>0)
interp.error(err);
return null;
} else if (name.equals("append")) {
String err = IJ.append(getFirstString(), getLastString());
if (err!=null) interp.error(err);
return null;
} else if (name.equals("saveString")) {
String err = IJ.saveString(getFirstString(), getLastString());
if (err!=null) interp.error(err);
return null;
} else if (name.startsWith("setDefaultDir")) {
OpenDialog.setDefaultDirectory(getStringArg());
return null;
} else if (name.startsWith("getDefaultDir")) {
String dir = OpenDialog.getDefaultDirectory();
return dir!=null?dir:"";
}
File f = new File(getStringArg());
if (name.equals("getLength")||name.equals("length"))
return ""+f.length();
else if (name.equals("getNameWithoutExtension")) {
String name2 = f.getName();
int dotIndex = name2.lastIndexOf(".");
if (dotIndex>=0)
name2 = name2.substring(0, dotIndex);
return name2;
} else if (name.equals("getName")) {
return f.getName();
} else if (name.equals("getDirectory")) {
String parent = f.getParent();
return parent!=null?parent.replaceAll("\\\\", "/")+"/":"";
} else if (name.equals("getAbsolutePath"))
return f.getAbsolutePath();
else if (name.equals("getParent"))
return f.getParent();
else if (name.equals("exists"))
return f.exists()?"1":"0";
else if (name.equals("isDirectory"))
return f.isDirectory()?"1":"0";
else if (name.equals("makeDirectory")||name.equals("mkdir")) {
f.mkdir(); return null;
} else if (name.equals("lastModified"))
return ""+f.lastModified();
else if (name.equals("dateLastModified"))
return (new Date(f.lastModified())).toString();
else if (name.equals("delete")) {
return f.delete()?"1":"0";
} else
interp.error("Unrecognized File function "+name);
return null;
}
String nameWithoutExtension() {
String name = OpenDialog.getLastName();
if (name==null) return "";
int dotIndex = name.lastIndexOf(".");
if (dotIndex>=0 && (name.length()-dotIndex)<=5)
name = name.substring(0, dotIndex);
return name;
}
boolean checkPath(File f) {
String path = f.getPath();
if (path.equals("0") || path.equals("NaN")) {
interp.error("Invalid path");
return false;
} else
return true;
}
String openDialog() {
String title = getStringArg();
OpenDialog od = new OpenDialog(title, null);
String directory = od.getDirectory();
String name = od.getFileName();
if (name==null)
return "";
else
return directory+name;
}
void setSelectionName() {
Roi roi = getImage().getRoi();
if (roi==null)
interp.error("No selection");
else
roi.setName(getStringArg());
}
String selectionName() {
Roi roi = getImage().getRoi();
String name = null;
if (roi==null)
interp.error("No selection");
else
name = roi.getName();
return name!=null?name:"";
}
String openFile() {
if (writer!=null) {
interp.error("Currently, only one file can be open at a time");
return"";
}
String path = getFirstString();
String defaultName = null;
if (interp.nextToken()==')')
interp.getRightParen();
else
defaultName = getLastString();
if (path.equals("") || defaultName!=null) {
String title = defaultName!=null?path:"openFile";
defaultName = defaultName!=null?defaultName:"log.txt";
SaveDialog sd = new SaveDialog(title, defaultName, ".txt");
if (sd.getFileName()==null) return "";
path = sd.getDirectory()+sd.getFileName();
} else {
File file = new File(path);
if (file.exists() && !(path.endsWith(".txt")||path.endsWith(".java")||path.endsWith(".xls")
||path.endsWith(".csv")||path.endsWith(".tsv")||path.endsWith(".ijm")
||path.endsWith(".html")||path.endsWith(".htm")))
interp.error("File exists and suffix is not '.txt', '.java', etc.");
}
try {
FileOutputStream fos = new FileOutputStream(path);
BufferedOutputStream bos = new BufferedOutputStream(fos);
writer = new PrintWriter(bos);
}
catch (IOException e) {
interp.error("File open error \n\""+e.getMessage()+"\"\n");
return "";
}
return "~0~";
}
String openAsString() {
String path = getStringArg();
String str = IJ.openAsString(path);
if (str==null)
interp.done = true;
else if (str.startsWith("Error: "))
interp.error(str);
return str;
}
String openAsRawString() {
int max = 5000;
String path = getFirstString();
boolean specifiedMax = false;
if (interp.nextToken()==',') {
max = (int)getNextArg();
specifiedMax = true;
}
interp.getRightParen();
if (path.equals("")) {
OpenDialog od = new OpenDialog("Open As String", "");
String directory = od.getDirectory();
String name = od.getFileName();
if (name==null) return "";
path = directory + name;
}
String str = "";
File file = new File(path);
if (!file.exists())
interp.error("File not found");
try {
StringBuffer sb = new StringBuffer(5000);
int len = (int)file.length();
if (max>len || (path.endsWith(".txt")&&!specifiedMax))
max = len;
InputStream in = new BufferedInputStream(new FileInputStream(path));
DataInputStream dis = new DataInputStream(in);
byte[] buffer = new byte[max];
dis.readFully(buffer);
dis.close();
char[] buffer2 = new char[buffer.length];
for (int i=0; i0) {
argClasses = new Class[args.length];
for(int i=0;i0) {
try {
Class[] argClasses = new Class[args.length];
for(int i=0;iimp.getNChannels())
interp.error("Invalid channel: "+channel);
if (((CompositeImage)imp).getMode()!=IJ.COMPOSITE)
((CompositeImage)imp).setMode(IJ.COMPOSITE);
boolean[] active = ((CompositeImage)imp).getActiveChannels();
active[channel-1] = active[channel-1]?false:true;
imp.updateAndDraw();
Channels.updateChannels();
}
void setDisplayMode(ImagePlus imp, String mode) {
mode = mode.toLowerCase(Locale.US);
if (!imp.isComposite())
interp.error("Composite image required");
int m = -1;
if (mode.equals("composite"))
m = IJ.COMPOSITE;
else if (mode.equals("color"))
m = IJ.COLOR;
else if (mode.startsWith("gray"))
m = IJ.GRAYSCALE;
if (m==-1)
interp.error("Invalid mode");
((CompositeImage)imp).setMode(m);
imp.updateAndDraw();
}
void swapStackImages(ImagePlus imp) {
int n1 = (int)getFirstArg();
int n2 = (int)getLastArg();
ImageStack stack = imp.getStack();
int size = stack.size();
if (n1<1||n1>size||n2<1||n2>size)
interp.error("Argument out of range");
Object pixels = stack.getPixels(n1);
String label = stack.getSliceLabel(n1);
stack.setPixels(stack.getPixels(n2), n1);
stack.setSliceLabel(stack.getSliceLabel(n2), n1);
stack.setPixels(pixels, n2);
stack.setSliceLabel(label, n2);
int current = imp.getCurrentSlice();
if (imp.isComposite()) {
CompositeImage ci = (CompositeImage)imp;
if (ci.getMode()==IJ.COMPOSITE) {
ci.reset();
imp.updateAndDraw();
imp.repaintWindow();
return;
}
}
if (n1==current || n2==current)
imp.setStack(null, stack);
}
void getDisplayMode(ImagePlus imp) {
Variable v = getVariableArg();
String mode = "";
if (imp.isComposite())
mode = ((CompositeImage)imp).getModeAsString();
v.setString(mode);
}
void getPosition(ImagePlus imp) {
Variable channel = getFirstVariable();
Variable slice = getNextVariable();
Variable frame = getLastVariable();
int c = imp.getChannel();
int z = imp.getSlice();
int t = imp.getFrame();
if (c*z*t>imp.getStackSize())
{c=1; z=imp.getCurrentSlice(); t=1;}
channel.setValue(c);
slice.setValue(z);
frame.setValue(t);
}
void setPosition(ImagePlus img) {
int channel = (int)getFirstArg();
int slice = (int)getNextArg();
int frame = (int)getLastArg();
img.setPosition(channel, slice, frame);
}
void setDimensions(ImagePlus img) {
int c = (int)getFirstArg();
int z = (int)getNextArg();
int t = (int)getLastArg();
img.setDimensions(c, z, t);
if (img.getWindow()==null) img.setOpenAsHyperStack(true);
}
void setTool() {
interp.getLeftParen();
if (isStringArg()) {
boolean ok = IJ.setTool(getString());
if (!ok) interp.error("Unrecognized tool name");
} else
IJ.setTool((int)interp.getExpression());
interp.getRightParen();
}
String doToString() {
String s = getFirstString();
interp.getToken();
if (interp.token==',') {
double value = Tools.parseDouble(s);
s = IJ.d2s(value, (int)interp.getExpression());
interp.getToken();
}
if (interp.token!=')') interp.error("')' expected");
return s;
}
double matches(String str) {
str = getStringFunctionArg(str);
String regex = getString();
interp.getRightParen();
try {
return str.matches(regex)?1.0:0.0;
} catch (Exception e) {
interp.error(""+e);
return 0.0;
}
}
void waitForUser() {
IJ.wait(50);
if (waitForUserDialog!=null && waitForUserDialog.isShowing())
interp.error("Duplicate call");
String title = "Action Required";
String text = " Click \"OK\" to continue ";
if (interp.nextToken()=='(') {
title = getFirstString();
if (interp.nextToken()==',')
text = getLastString();
else {
text = title;
title = "Action Required";
interp.getRightParen();
}
}
waitForUserDialog = new WaitForUserDialog(title, text);
Interpreter instance = Interpreter.getInstance();
interp.waitingForUser = true;
waitForUserDialog.show();
interp.waitingForUser = false;
Interpreter.setInstance(instance); // works around bug caused by use of drawing tools
if (waitForUserDialog.escPressed())
throw new RuntimeException(Macro.MACRO_CANCELED);
}
void abortDialog() {
if (waitForUserDialog!=null && waitForUserDialog.isVisible())
waitForUserDialog.close();
}
double getStringWidth() {
resetImage();
ImageProcessor ip = getProcessor();
setFont(ip);
return ip.getStringWidth(getStringArg());
}
String doList() {
interp.getToken();
if (interp.token!='.')
interp.error("'.' expected");
interp.getToken();
if (!(interp.token==WORD||interp.token==ARRAY_FUNCTION||interp.token==NUMERIC_FUNCTION))
interp.error("Function name expected: ");
if (props==null)
props = new Properties();
String value = null;
String name = interp.tokenString;
if (name.equals("get")) {
value = props.getProperty(getStringArg());
value = value!=null?value:"";
} else if (name.equals("getValue")) {
value = props.getProperty(getStringArg());
if (value==null) interp.error("Value not found");
} else if (name.equals("set")||name.equals("add")||name.equals("put"))
props.setProperty(getFirstString(), getLastString());
else if (name.equals("clear")||name.equals("reset")) {
interp.getParens();
props.clear();
} else if (name.equals("setList"))
setPropertiesFromString(props);
else if (name.equals("getList"))
value = getPropertiesAsString(props);
else if (name.equals("size")||name.equals("getSize")) {
interp.getParens();
value = ""+props.size();
} else if (name.equals("setMeasurements"))
setMeasurements();
else if (name.equals("setCommands"))
setCommands();
else if (name.equals("indexOf")) {
int index = -1;
String key = getStringArg();
int size = props.size();
String[] keyArr = new String[size];
String[] valueArr = new String[size];
listToArrays(keyArr, valueArr);
for (int i = 0; i < size; i++) {
if (keyArr[i].equals(key)) {
index = i;
break;
}
}
value = "" + index;
} else if (name.equals("fromArrays")) {
interp.getLeftParen();
String[] keys = getStringArray();
interp.getComma();
String[] values = getStringArray();
if (values.length != keys.length) {
interp.error("Arrays must have same length");
}
props.clear();
for (int i = 0; i < keys.length; i++) {
if (keys[i].equals("")) {
interp.error("Key cannot be an empty string");
}
props.setProperty(keys[i], values[i]);
}
interp.getRightParen();
} else if (name.equals("toArrays")) {
Variable keys = getFirstArrayVariable();
Variable values = getLastArrayVariable();
int size = props.size();
String[] keyArr = new String[size];
String[] valueArr = new String[size];
listToArrays(keyArr, valueArr);
Variable[] keysVar, valuesVar;
keysVar = new Variable[size];
valuesVar = new Variable[size];
for (int i = 0; i < size; i++) {
keysVar[i] = new Variable();
keysVar[i].setString(keyArr[i]);
valuesVar[i] = new Variable();
valuesVar[i].setString(valueArr[i]);
}
keys.setArray(keysVar);
values.setArray(valuesVar);
} else {
interp.error("Unrecognized List function");
}
return value;
}
void listToArrays(String[] keys, String[] values) {
Vector v = new Vector();
for (Enumeration en = props.keys(); en.hasMoreElements();) {
v.addElement(en.nextElement());
}
for (int i = 0; i < keys.length; i++) {
keys[i] = (String) v.elementAt(i);
}
Arrays.sort(keys);
for (int i = 0; i < keys.length; i++) {
values[i] = (String) props.get(keys[i]);
}
}
void setCommands() {
interp.getParens();
Hashtable commands = Menus.getCommands();
props = new Properties();
for (Enumeration en=commands.keys(); en.hasMoreElements();) {
String command = (String)en.nextElement();
props.setProperty(command, (String)commands.get(command));
}
}
void setMeasurements() {
String arg = "";
if (interp.nextToken()=='(') {
interp.getLeftParen();
if (interp.nextToken() != ')')
arg = getString().toLowerCase(Locale.US);
interp.getRightParen();
}
props.clear();
ImagePlus imp = getImage();
int measurements = ALL_STATS + SLICE;
if (arg.contains("limit"))
measurements += LIMIT;
ImageStatistics stats = imp.getStatistics(measurements);
ResultsTable rt = new ResultsTable();
Analyzer analyzer = new Analyzer(imp, measurements, rt);
analyzer.saveResults(stats, imp.getRoi());
for (int i=0; i<=rt.getLastColumn(); i++) {
if (rt.columnExists(i)) {
String name = rt.getColumnHeading(i);
String value = ""+rt.getValueAsDouble(i, 0);
props.setProperty(name, value);
}
}
}
void makePoint() {
double x = getFirstArg();
double y = getNextArg();
String options = null;
if (interp.nextToken()==',')
options = getNextString();
interp.getRightParen();
if (options==null) {
if ((int)x==x && (int)y==y)
IJ.makePoint((int)x, (int)y);
else
IJ.makePoint(x, y);
} else
getImage().setRoi(new PointRoi(x, y, options));
resetImage();
shiftKeyDown = altKeyDown = false;
}
void makeText() {
String text = getFirstString();
int x = (int)getNextArg();
int y = (int)getLastArg();
ImagePlus imp = getImage();
Font font = this.font;
boolean nullFont = font==null;
if (nullFont)
font = imp.getProcessor().getFont();
TextRoi roi = new TextRoi(x, y, text, font);
if (!nullFont)
roi.setAntiAlias(antialiasedText);
imp.setRoi(roi);
}
void makeEllipse() {
ImagePlus imp = getImage();
Roi previousRoi = imp.getRoi();
if (shiftKeyDown||altKeyDown)
imp.saveRoi();
double x1 = getFirstArg();
double y1 = getNextArg();
double x2 = getNextArg();
double y2 = getNextArg();
double aspectRatio = getLastArg();
Roi roi = new EllipseRoi(x1,y1,x2,y2,aspectRatio);
imp.setRoi(roi);
if (previousRoi!=null && roi!=null)
updateRoi(roi);
resetImage();
shiftKeyDown = altKeyDown = false;
}
double fit() {
interp.getToken();
if (interp.token!='.')
interp.error("'.' expected");
interp.getToken();
if (!(interp.token==WORD||interp.token==ARRAY_FUNCTION))
interp.error("Function name expected: ");
if (props==null)
props = new Properties();
String name = interp.tokenString;
if (name.equals("doFit"))
return fitCurve();
else if (name.equals("getEquation"))
return getEquation();
else if (name.equals("nEquations")) {
interp.getParens();
return CurveFitter.fitList.length;
} else if (name.equals("showDialog")) {
showFitDialog = true;
return Double.NaN;
} else if (name.equals("logResults")) {
logFitResults = true;
return Double.NaN;
}
if (fitter==null)
interp.error("No fit");
if (name.equals("f"))
return fitter.f(fitter.getParams(), getArg());
else if (name.equals("plot")) {
interp.getParens();
Fitter.plot(fitter);
return Double.NaN;
} else if (name.equals("nParams")) {
interp.getParens();
return fitter.getNumParams();
} else if (name.equals("p")) {
int index = (int)getArg();
checkIndex(index, 0, fitter.getNumParams()-1);
double[] p = fitter.getParams();
return indexlen) i2 = len;
int len2 = i2-i1;
if (len2<0) len2=0;
if (len2>len) len2=len;
interp.getRightParen();
Variable[] a2 = new Variable[len2];
for (int i=0; ilen) size = len;
Variable[] a2 = new Variable[size];
for (int i=0; imax) max = value;
}
minv.setValue(min);
if (maxv!=null) maxv.setValue(max);
if (mean!=null) mean.setValue(sum/n);
if (std!=null) {
double stdDev = (n*sum2-sum*sum)/n;
stdDev = Math.sqrt(stdDev/(n-1.0));
std.setValue(stdDev);
}
return a;
}
Variable[] getSequence() {
int n = (int)getArg();
Variable[] a = new Variable[n];
for (int i=0; i= 180.0)
phi -= 360.0;
vAngles[mid] = phi;
}
for (int i = 0; i < len; i++)
a2[i] = new Variable(vAngles[i]);
return a2;
}
Variable[] showArray() {
int maxLength = 0;
String title = "Arrays";
ArrayList arrays = new ArrayList();
ArrayList names = new ArrayList();
interp.getLeftParen();
do {
if (isStringArg() && !isArrayArg())
title = getString();
else {
int symbolTableAddress = pgm.code[interp.pc+1]>>TOK_SHIFT;
names.add(pgm.table[symbolTableAddress].str);
Variable[] a = getArray();
arrays.add(a);
if (a.length>maxLength)
maxLength = a.length;
}
interp.getToken();
} while (interp.token==',');
if (interp.token!=')')
interp.error("')' expected");
int n = arrays.size();
if (n==1) {
if (title.equals("Arrays"))
title = (String)names.get(0);
names.set(0, "Value");
}
ResultsTable rt = new ResultsTable();
//rt.setPrecision(Analyzer.getPrecision());
int openParenIndex = title.indexOf("(");
boolean showRowNumbers = false;
if (openParenIndex>=0) {
String options = title.substring(openParenIndex, title.length());
title = title.substring(0, openParenIndex);
title = title.trim();
showRowNumbers = options.contains("row") || options.contains("1");
if (!showRowNumbers && options.contains("index")) {
for (int i=0; i=a.length) {
rt.setValue(heading, i, "");
continue;
}
String s = a[i].getString();
if (s!=null)
rt.setValue(heading, i, s);
else
rt.setValue(heading, i, a[i].getValue());
}
}
rt.show(title);
waitUntilActivated(title);
return null;
}
double charCodeAt() {
String str = getFirstString();
int index = (int)getLastArg();
checkIndex(index, 0, str.length()-1);
return str.charAt(index);
}
void doWand() {
int x = (int)getFirstArg();
int y = (int)getNextArg();
double tolerance = 0.0;
String mode = null;
if (interp.nextToken()==',') {
tolerance = getNextArg();
mode = getNextString();
}
interp.getRightParen();
IJ.doWand(x, y, tolerance, mode);
resetImage();
}
private String ijCall() {
interp.getToken();
if (interp.token!='.')
interp.error("'.' expected");
interp.getToken();
if (!(interp.token==WORD||interp.token==NUMERIC_FUNCTION))
interp.error("Function name expected: ");
String name = interp.tokenString;
if (name.equals("pad"))
return pad();
else if (name.equals("deleteRows"))
IJ.deleteRows((int)getFirstArg(), (int)getLastArg());
else if (name.equals("log"))
IJ.log(getStringArg());
else if (name.equals("freeMemory"))
{interp.getParens(); return IJ.freeMemory();}
else if (name.equals("currentMemory"))
{interp.getParens(); return ""+IJ.currentMemory();}
else if (name.equals("maxMemory"))
{interp.getParens(); return ""+IJ.maxMemory();}
else if (name.equals("getToolName"))
{interp.getParens(); return ""+IJ.getToolName();}
else if (name.equals("redirectErrorMessages"))
{interp.getParens(); IJ.redirectErrorMessages(); return null;}
else if (name.equals("renameResults"))
renameResults();
else if (name.equals("getFullVersion"))
{interp.getParens(); return ""+IJ.getFullVersion();}
else
interp.error("Unrecognized IJ function name");
return null;
}
private String pad() {
int intArg = 0;
String stringArg = null;
interp.getLeftParen();
if (isStringArg())
stringArg = getString();
else
intArg = (int)interp.getExpression();
int digits = (int)getLastArg();
if (stringArg!=null)
return IJ.pad(stringArg, digits);
else
return IJ.pad(intArg, digits);
}
private void renameResults() {
String arg1 = getFirstString();
String arg2 = null;
if (interp.nextToken()==')')
interp.getRightParen();
else
arg2 = getLastString();
if (resultsPending) {
ResultsTable rt = Analyzer.getResultsTable();
if (rt!=null && rt.size()>0)
rt.show("Results");
resultsPending = false;
}
if (arg2!=null)
IJ.renameResults(arg1, arg2);
else
IJ.renameResults(arg1);
}
double overlay() {
interp.getToken();
if (interp.token!='.')
interp.error("'.' expected");
interp.getToken();
if (!(interp.token==WORD||interp.token==ARRAY_FUNCTION
|| interp.token==PREDEFINED_FUNCTION||interp.token==USER_FUNCTION))
interp.error("Function name expected");
String name = interp.tokenString;
ImagePlus imp = getImage();
if (name.equals("lineTo"))
return overlayLineTo();
else if (name.equals("moveTo"))
return overlayMoveTo();
else if (name.equals("drawLine"))
return overlayDrawLine();
else if (name.equals("drawRect"))
return overlayDrawRectOrEllipse(imp, false);
else if (name.equals("drawEllipse"))
return overlayDrawRectOrEllipse(imp, true);
else if (name.equals("drawString"))
return overlayDrawString(imp);
else if (name.equals("add"))
return addDrawing(imp);
else if (name.equals("show"))
return showOverlay(imp);
else if (name.equals("hide"))
return hideOverlay(imp);
else if (name.equals("selectable"))
return overlaySelectable(imp);
else if (name.equals("remove"))
return removeOverlay(imp);
else if (name.equals("clear"))
return clearOverlay(imp);
else if (name.equals("paste")) {
interp.getParens();
if (overlayClipboard==null)
interp.error("Overlay clipboard empty");
getImage().setOverlay(overlayClipboard);
return Double.NaN;
} else if (name.equals("drawLabels")) {
overlayDrawLabels = getBooleanArg();
Overlay overlay = imp.getOverlay();
if (overlay!=null) {
overlay.drawLabels(overlayDrawLabels);
imp.draw();
}
return Double.NaN;
} else if (name.equals("useNamesAsLabels")) {
boolean useNames = getBooleanArg();
Overlay overlay = imp.getOverlay();
if (overlay!=null) {
overlay.drawNames(useNames);
imp.draw();
}
return Double.NaN;
}
Overlay overlay = imp.getOverlay();
int size = overlay!=null?overlay.size():0;
if (overlay==null && name.equals("size"))
return 0.0;
else if (name.equals("hidden"))
return overlay!=null && imp.getHideOverlay()?1.0:0.0;
else if (name.equals("addSelection") || name.equals("addRoi"))
return overlayAddSelection(imp, overlay);
else if (name.equals("setPosition")) {
addDrawingToOverlay(imp);
return overlaySetPosition(overlay);
} else if (name.equals("setFillColor"))
return overlaySetFillColor(overlay);
else if (name.equals("indexAt")) {
int x = (int)getFirstArg();
int y = (int)getLastArg();
return overlay!=null?overlay.indexAt(x,y):-1;
} else if (name.equals("getType")) {
int index = (int)getArg();
if (overlay==null || index==-1) return -1;
checkIndex(index, 0, size-1);
return overlay.get(index).getType();
}
if (overlay==null)
interp.error("No overlay");
if (name.equals("size")||name.equals("getSize"))
return size;
else if (name.equals("copy")) {
interp.getParens();
overlayClipboard = getImage().getOverlay();
return Double.NaN;
} else if (name.equals("removeSelection")||name.equals("removeRoi")) {
int index = (int)getArg();
checkIndex(index, 0, size-1);
overlay.remove(index);
imp.draw();
return Double.NaN;
} else if (name.equals("activateSelection")||name.equals("activateSelectionAndWait")||name.equals("activateRoi")) {
boolean waitForDisplayRefresh = name.equals("activateSelectionAndWait");
return activateSelection(imp, overlay, waitForDisplayRefresh);
} else if (name.equals("moveSelection")) {
int index = (int)getFirstArg();
int x = (int)getNextArg();
int y = (int)getLastArg();
checkIndex(index, 0, size-1);
Roi roi = overlay.get(index);
roi.setLocation(x, y);
imp.draw();
return Double.NaN;
} else if (name.equals("measure")) {
ResultsTable rt = overlay.measure(imp);
if (IJ.getInstance()==null)
Analyzer.setResultsTable(rt);
else
rt.show("Results");
} else if (name.equals("flatten")) {
IJ.runPlugIn("ij.plugin.OverlayCommands", "flatten");
return Double.NaN;
} else if (name.equals("setLabelFontSize")) {
int fontSize = (int)getFirstArg();
String options = null;
if (interp.nextToken()!=')')
options = getLastString();
else
interp.getRightParen();
overlay.setLabelFontSize(fontSize, options);
return Double.NaN;
} else if (name.equals("setLabelColor")) {
interp.getLeftParen();
Color color = getColor();
if (interp.nextToken()==',') {
interp.getComma();
Color ignore = getColor();
overlay.drawBackgrounds(true);
}
interp.getRightParen();
overlay.setLabelColor(color);
overlay.drawLabels(true);
return Double.NaN;
} else if (name.equals("setStrokeColor")) {
interp.getLeftParen();
Color color = getColor();
interp.getRightParen();
overlay.setStrokeColor(color);
return Double.NaN;
} else if (name.equals("setStrokeWidth")) {
overlay.setStrokeWidth(getArg());
return Double.NaN;
} else if (name.equals("removeRois")) {
overlay.remove(getStringArg());
return Double.NaN;
} else if (name.equals("getBounds")) {
return getOverlayElementBounds(overlay);
} else if (name.equals("cropAndSave")) {
Roi[] rois = overlay.toArray();
imp.cropAndSave(rois, getFirstString(), getLastString());
return Double.NaN;
} else
interp.error("Unrecognized function name");
return Double.NaN;
}
private double activateSelection(ImagePlus imp, Overlay overlay, boolean wait) {
int index = (int)getArg();
int size = overlay.size();
checkIndex(index, 0, size-1);
Roi roi = overlay.get(index);
if (roi==null)
return Double.NaN;;
if (imp.getStackSize()>1) {
if (imp.isHyperStack() && roi.hasHyperStackPosition()) {
int c = roi.getCPosition();
int z = roi.getZPosition();
int t = roi.getTPosition();
c = c>0?c:imp.getChannel();
z = z>0?z:imp.getSlice();
t = t>0?t:imp.getFrame();
imp.setPosition(c, z, t);
} else if (roi.getPosition()>0)
imp.setSlice(roi.getPosition());
}
if (wait) { // wait for display to finish updating
ImageCanvas ic = imp.getCanvas();
if (ic!=null) ic.setPaintPending(true);
imp.setRoi(roi, !Interpreter.isBatchMode());
long t0 = System.currentTimeMillis();
do {
IJ.wait(5);
} while (ic!=null && ic.getPaintPending() && System.currentTimeMillis()-t0<50);
} else
imp.setRoi(roi, !Interpreter.isBatchMode());
if (Analyzer.addToOverlay())
ResultsTable.selectRow(roi);
return Double.NaN;
}
private double getOverlayElementBounds(Overlay overlay) {
int index = (int)getFirstArg();
Variable x = getNextVariable();
Variable y = getNextVariable();
Variable width = getNextVariable();
Variable height = getLastVariable();
Roi roi = overlay.get(index);
if (roi==null)
return Double.NaN;
Rectangle2D.Double r = roi.getFloatBounds();
x.setValue(r.x);
y.setValue(r.y);
width.setValue(r.width);
height.setValue(r.height);
return Double.NaN;
}
double overlayAddSelection(ImagePlus imp, Overlay overlay) {
String strokeColor = null;
double strokeWidth = Double.NaN;
String fillColor = null;
if (interp.nextToken()=='(') {
interp.getLeftParen();
if (isStringArg()) {
strokeColor = getString();
if (interp.nextToken()==',') {
interp.getComma();
strokeWidth = interp.getExpression();
if (interp.nextToken()==',') {
interp.getComma();
fillColor = interp.getString();
}
}
}
interp.getRightParen();
}
Roi roi = imp.getRoi();
if (roi==null)
interp.error("No selection");
if (offscreenOverlay!=null) {
imp.setOverlay(offscreenOverlay);
offscreenOverlay = null;
overlay = imp.getOverlay();
}
if (overlay==null)
overlay = new Overlay();
if (strokeColor!=null && !strokeColor.equals("")) {
roi.setFillColor(null);
roi.setStrokeColor(Colors.decode(strokeColor, Color.black));
}
if (!Double.isNaN(strokeWidth))
roi.setStrokeWidth(strokeWidth);
if (fillColor!=null && !fillColor.equals(""))
roi.setFillColor(Colors.decode(fillColor, Color.black));
overlay.add(roi);
imp.setOverlay(overlay);
return Double.NaN;
}
double overlaySetPosition(Overlay overlay) {
int c=0, z=0, t=0;
int nargs = 1;
int n = (int)getFirstArg();
if (interp.nextToken()==',') {
nargs = 3;
c = n;
z = (int)getNextArg();
t = (int)getLastArg();
} else
interp.getRightParen();
if (overlay==null)
overlay = offscreenOverlay;
if (overlay==null)
interp.error("No overlay");
int size = overlay.size();
if (size==0)
return Double.NaN;
if (nargs==1)
overlay.get(size-1).setPosition(n);
else if (nargs==3)
overlay.get(size-1).setPosition(c, z, t);
return Double.NaN;
}
double overlaySetFillColor(Overlay overlay) {
interp.getLeftParen();
Color color = getColor();
interp.getRightParen();
if (overlay==null)
overlay = offscreenOverlay;
if (overlay==null)
interp.error("No overlay");
int size = overlay.size();
if (size>0)
overlay.get(size-1).setFillColor(color);
return Double.NaN;
}
double overlayMoveTo() {
if (overlayPath==null)
overlayPath = new GeneralPath();
interp.getLeftParen();
float x = (float)interp.getExpression();
interp.getComma();
float y = (float)interp.getExpression();
interp.getRightParen();
overlayPath.moveTo(x, y);
return Double.NaN;
}
double overlayLineTo() {
if (overlayPath==null) {
overlayPath = new GeneralPath();
overlayPath.moveTo(0, 0);
}
interp.getLeftParen();
float x = (float)interp.getExpression();
interp.getComma();
float y = (float)interp.getExpression();
interp.getRightParen();
overlayPath.lineTo(x, y);
return Double.NaN;
}
double overlayDrawLine() {
if (overlayPath==null) overlayPath = new GeneralPath();
interp.getLeftParen();
float x1 = (float)interp.getExpression();
interp.getComma();
float y1 = (float)interp.getExpression();
interp.getComma();
float x2 = (float)interp.getExpression();
interp.getComma();
float y2 = (float)interp.getExpression();
interp.getRightParen();
overlayPath.moveTo(x1, y1);
overlayPath.lineTo(x2, y2);
return Double.NaN;
}
double overlayDrawRectOrEllipse(ImagePlus imp, boolean ellipse) {
addDrawingToOverlay(imp);
float x = (float)Math.round(getFirstArg());
float y = (float)Math.round(getNextArg());
float w = (float)Math.round(getNextArg());
float h = (float)Math.round(getLastArg());
Shape shape = null;
if (ellipse)
shape = new Ellipse2D.Float(x, y, w, h);
else
shape = new Rectangle2D.Float(x, y, w, h);
Roi roi = new ShapeRoi(shape);
addRoi(imp, roi);
return Double.NaN;
}
double overlayDrawString(ImagePlus imp) {
addDrawingToOverlay(imp);
String text = getFirstString();
int x = (int)getNextArg();
int y = (int)getNextArg();
double angle = 0.0;
if (interp.nextToken()==',')
angle = getLastArg();
else
interp.getRightParen();
Font font = this.font;
boolean nullFont = font==null;
if (nullFont)
font = imp.getProcessor().getFont();
TextRoi roi = new TextRoi(text, x, y, font); // use drawString() compatible constructor
if (!nullFont && !antialiasedText)
roi.setAntiAlias(false);
roi.setAngle(angle);
roi.setJustification(justification);
addRoi(imp, roi);
return Double.NaN;
}
double addDrawing(ImagePlus imp) {
interp.getParens();
addDrawingToOverlay(imp);
return Double.NaN;
}
void addDrawingToOverlay(ImagePlus imp) {
if (overlayPath==null)
return;
Roi roi = new ShapeRoi(overlayPath);
overlayPath = null;
addRoi(imp, roi);
}
void addRoi(ImagePlus imp, Roi roi){
Overlay overlay = imp.getOverlay();
if (overlay==null || overlay.size()==0) {
if (offscreenOverlay==null)
offscreenOverlay = new Overlay();
overlay = offscreenOverlay;
}
if (globalColor!=null)
roi.setStrokeColor(globalColor);
roi.setStrokeWidth(getProcessor().getLineWidth());
overlay.add(roi);
}
double showOverlay(ImagePlus imp) {
interp.getParens();
addDrawingToOverlay(imp);
if (offscreenOverlay!=null) {
imp.setOverlay(offscreenOverlay);
offscreenOverlay = null;
} else
imp.setHideOverlay(false);
return Double.NaN;
}
double hideOverlay(ImagePlus imp) {
interp.getParens();
imp.setHideOverlay(true);
return Double.NaN;
}
double overlaySelectable(ImagePlus imp) {
boolean selectable = getBooleanArg();
Overlay overlay = imp.getOverlay();
if (overlay!=null)
overlay.selectable(selectable);
return Double.NaN;
}
double removeOverlay(ImagePlus imp) {
interp.getParens();
imp.setOverlay(null);
offscreenOverlay = null;
return Double.NaN;
}
double clearOverlay(ImagePlus imp) {
interp.getParens();
offscreenOverlay = null;
Overlay overlay = imp.getOverlay();
if (overlay!=null)
overlay.clear();
return Double.NaN;
}
private Variable doTable() {
interp.getToken();
if (interp.token!='.')
interp.error("'.' expected");
interp.getToken();
if (!(interp.token==WORD || interp.token==NUMERIC_FUNCTION || interp.token==PREDEFINED_FUNCTION || interp.token==STRING_FUNCTION))
interp.error("Function name expected: ");
String name = interp.tokenString;
if (name.equals("create"))
return resetTable();
else if (name.equals("size"))
return new Variable(getResultsTable(getTitleArg()).size());
else if (name.equals("get"))
return new Variable(getResult(getRT(null)));
else if (name.equals("getColumn"))
return getColumn();
else if (name.equals("getString"))
return new Variable(getResultString(getRT(null)));
else if (name.equals("set"))
return setTableValue();
else if (name.equals("setColumn"))
return setTableColumn();
else if (name.equals("reset"))
return resetTable();
else if (name.equals("update"))
return updateTable();
else if (name.equals("applyMacro"))
return applyMacroToTable();
else if (name.equals("deleteRows"))
return deleteRows();
else if (name.equals("deleteColumn"))
return deleteColumn();
else if (name.equals("renameColumn"))
return renameColumn();
else if (name.equals("save"))
return saveTable();
else if (name.equals("open"))
return openTable();
else if (name.equals("title"))
return new Variable(getResultsTable(getTitleArg()).getTitle());
else if (name.equals("headings"))
return new Variable(getResultsTable(getTitleArg()).getColumnHeadings());
else if (name.equals("allHeadings"))
return getAllHeadings();
else if (name.equals("showRowNumbers"))
return showRowNumbers(true);
else if (name.equals("showRowIndexes"))
return showRowNumbers(false);
else if (name.startsWith("saveColumnHeader"))
return saveColumnHeaders();
else if (name.equals("sort"))
return sortTable();
else if (name.equals("hideRowNumbers")) {
getResultsTable(getTitleArg()).showRowNumbers(false);
return null;
} else if (name.equals("rename")) {
renameResults();
return null;
} else if (name.startsWith("showArray")) {
showArray();
return null;
} else if (name.equals("getSelectionStart"))
return getSelectionStart();
else if (name.equals("getSelectionEnd"))
return getSelectionEnd();
else if (name.equals("setSelection"))
return setSelection();
else if (name.equals("setLocAndSize") || name.equals("setLocationAndSize"))
return setTableLocAndSize();
else
interp.error("Unrecognized function name");
return null;
}
private Variable setTableLocAndSize() {
double x = getFirstArg();
double y = getNextArg();
double width = getNextArg();
double height = getNextArg();
String title = getTitle();
if (title==null) {
ResultsTable rt = getResultsTable(title);
title = rt.getTitle();
}
Frame frame = WindowManager.getFrame(title);
if (frame!=null) {
Point loc = frame.getLocation();
Dimension size = frame.getSize();
frame.setLocation(Double.isNaN(x)?loc.x:(int)x, Double.isNaN(y)?loc.y:(int)y);
frame.setSize(Double.isNaN(width)?size.width:(int)width, Double.isNaN(height)?size.height:(int)height);
}
return null;
}
private Variable setSelection() {
interp.getLeftParen();
double from = interp.getExpression();
interp.getComma();
double to = interp.getExpression();
ResultsTable rt = getResultsTable(getTitle());
String title = rt.getTitle();
Frame f = WindowManager.getFrame(title);
if (f!=null && (f instanceof TextWindow)){
TextWindow tWin = (TextWindow)f;
if (from == -1 && to == -1)
tWin.getTextPanel().resetSelection();
else
tWin.getTextPanel().setSelection((int)from, (int)to);
return null;
}
interp.error("\""+title+"\" table not found");
return null;
}
private Variable getSelectionStart() {
int selStart = -1;
ResultsTable rt = getResultsTable(getTitleArg());
String title = rt.getTitle();
Frame f = WindowManager.getFrame(title);
if (f!=null && (f instanceof TextWindow)){
TextWindow tWin = (TextWindow)f;
selStart = tWin.getTextPanel().getSelectionStart();
return new Variable(selStart);
}
return new Variable(selStart);
}
private Variable getSelectionEnd() {
int selEnd = -1;
ResultsTable rt = getResultsTable(getTitleArg());
String title = rt.getTitle();
Frame f = WindowManager.getFrame(title);
if (f!=null && (f instanceof TextWindow)){
TextWindow tWin = (TextWindow)f;
selEnd = tWin.getTextPanel().getSelectionEnd();
return new Variable(selEnd);
}
interp.error("\""+title+"\" table not found");
return new Variable(selEnd);
}
private Variable setTableValue() {
ResultsTable rt = getRT(null);
setResult(rt);
return null;
}
private Variable setTableColumn() {
String column = getFirstString();
Variable[] array = new Variable[0];
if (interp.nextToken()!=')') {
interp.getComma();
array = getArray();
}
ResultsTable rt = getResultsTable(getTitle());
rt.setColumn(column, array);
rt.show(rt.getTitle());
return null;
}
private Variable updateTable() {
String title = getTitleArg();
ResultsTable rt = getResultsTable(title);
rt.show(rt.getTitle());
unUpdatedTable = null;
if (rt==Analyzer.getResultsTable())
resultsPending = false;
return null;
}
private Variable resetTable() {
String title = getTitleArg();
ResultsTable rt = null;
if ("Results".equals(title)) {
rt = Analyzer.getResultsTable();
rt.showRowNumbers(false);
rt.reset();
rt.show("Results");
toFront("Results");
return null;
}
if (getRT(title)==null) {
rt = new ResultsTable();
rt.show(title);
waitUntilActivated(title);
} else {
rt = getResultsTable(title);
rt.reset();
toFront(title);
if (rt==Analyzer.getResultsTable())
resultsPending = true;
}
return null;
}
private void waitUntilActivated(String title) {
long start = System.currentTimeMillis();
while (true) {
IJ.wait(5);
Frame frame = WindowManager.getFrontWindow();
String title2 = frame!=null?frame.getTitle():null;
if (title.equals(title2))
return;
if ((System.currentTimeMillis()-start)>200)
break;
}
}
private void toFront(String title) {
if (title==null)
return;
Frame frame = WindowManager.getFrame(title);
if (frame!=null) {
frame.toFront();
WindowManager.setWindow(frame);
}
}
private Variable applyMacroToTable() {
String macro = getFirstString();
String title = getTitle();
if (macro.equals("Results")) {
macro = title;
title = "Results";
}
ResultsTable rt = getResultsTable(title);
rt.applyMacro(macro);
rt.show(rt.getTitle());
return null;
}
private Variable deleteRows() {
int row1 = (int)getFirstArg();
int row2 = (int)getNextArg();
String title = getTitle();
ResultsTable rt = getResultsTable(title);
int tableSize = rt.size();
rt.deleteRows(row1, row2);
ImagePlus imp = WindowManager.getCurrentImage();
if (imp!=null)
Overlay.updateTableOverlay(imp, row1, row2, tableSize);
rt.show(title);
return null;
}
private Variable deleteColumn() {
String column = getFirstString();
String title = getTitle();
ResultsTable rt = getResultsTable(title);
try {
rt.deleteColumn(column);
unUpdatedTable = rt;
} catch (Exception e) {
interp.error(e.getMessage());
}
return null;
}
private Variable getColumn() {
String col = getFirstString();
ResultsTable rt = getResultsTable(getTitle());
Variable column = null;
try {
column = new Variable(rt.getColumnAsVariables(col));
} catch (Exception e) {
interp.error(e.getMessage());
}
return column;
}
private Variable renameColumn() {
String oldName = getFirstString();
String newName = getNextString();
String title = getTitle();
ResultsTable rt = getResultsTable(title);
try {
rt.renameColumn(oldName, newName);
unUpdatedTable = rt;
} catch (Exception e) {
interp.error(e.getMessage());
}
return null;
}
private Variable showRowNumbers(boolean numbers) {
boolean show = (int)getFirstArg()!=0;
ResultsTable rt = getResultsTable(getTitle());
if (numbers)
rt.showRowNumbers(show);
else
rt.showRowIndexes(show);
unUpdatedTable = rt;
return null;
}
private Variable saveColumnHeaders() {
boolean save = (int)getFirstArg()!=0;
ResultsTable rt = getResultsTable(getTitle());
rt.saveColumnHeaders(save);
unUpdatedTable = rt;
return null;
}
private Variable sortTable() {
String column = getFirstString();
ResultsTable rt = getResultsTable(getTitle());
try {
rt.sort(column);
} catch (Exception e) {
interp.error(e.getMessage());
}
rt.show(rt.getTitle());
return null;
}
private Variable saveTable() {
String path = getFirstString();
ResultsTable rt = getResultsTable(getTitle());
try {
rt.saveAs(path);
} catch (Exception e) {
String msg = e.getMessage();
if (!msg.startsWith("Macro canceled"))
interp.error(msg);
}
return null;
}
private Variable openTable() {
String path = getFirstString();
String title = getTitle();
if (title==null)
title = new File(path).getName();
ResultsTable rt = null;
try {
rt = rt.open(path);
} catch (Exception e) {
String msg = e.getMessage();
if (!msg.startsWith("Macro canceled"))
interp.error(msg);
}
rt.show(title);
return null;
}
private Variable getAllHeadings() {
interp.getParens();
String[] headings = ResultsTable.getDefaultHeadings();
StringBuilder sb = new StringBuilder(250);
for (int i=0; i255) r=255; if (g>255) g=255; if (b>255) b=255;
return new Color(r, g, b);
}
}
private void getContainedPoints(Roi roi) {
Variable xCoordinates = getFirstArrayVariable();
Variable yCoordinates = getLastArrayVariable();
FloatPolygon points = roi.getContainedFloatPoints();
Variable[] xa = new Variable[points.npoints];
Variable[] ya = new Variable[points.npoints];
for (int i=0; i255)
interp.error("Group out of range");
rm.setGroup(group);
return null;
} else if (name.equals("selectGroup")) {
rm.selectGroup((int)getArg());
return null;
} else if (name.equals("getName")) {
String roiName = rm.getName((int)getArg());
return new Variable(roiName!=null?roiName:"");
} else if (name.equals("setPosition")) {
int position = (int)getArg();
rm.setPosition(position);
return null;
} else if (name.equals("multiCrop")) {
rm.multiCrop(getFirstString(),getLastString());
return null;
} else
interp.error("Unrecognized RoiManager function");
return null;
}
private Variable doProperty() {
interp.getToken();
if (interp.token!='.')
interp.error("'.' expected");
interp.getToken();
if (!(interp.token==WORD||interp.token==STRING_FUNCTION||interp.token==NUMERIC_FUNCTION||interp.token==ARRAY_FUNCTION))
interp.error("Function name expected: ");
String name = interp.tokenString;
ImagePlus imp = getImage();
if (name.equals("set")) {
String key = getFirstString();
String value = getLastString();
if (value.length()==0) value = null;
imp.setProp(key, value);
return null;
} else if (name.equals("get")) {
String value = imp.getProp(getStringArg());
return new Variable(value!=null?value:"");
} else if (name.equals("getNumber")) {
String svalue = imp.getProp(getStringArg());
double nvalue = svalue!=null?Tools.parseDouble(svalue):Double.NaN;
return new Variable(nvalue);
} else if (name.equals("getInfo")) {
interp.getParens();
String value = (String)imp.getProperty("Info");
return new Variable(value!=null?value:"");
} else if (name.equals("setInfo")) {
imp.setProperty("Info", getStringArg());
return null;
} else if (name.equals("getSliceLabel")) {
String value = imp.getStack().getSliceLabel((int)getArg());
Variable v = new Variable(value!=null?value:"");
return v;
} else if (name.equals("setSliceLabel")) {
String label = getFirstString();
int slice = (int)getLastArg();
if (slice<1 || slice>imp.getStackSize())
interp.error("Argument must be >=1 and <="+imp.getStackSize());
imp.getStack().setSliceLabel(label, slice);
if (!Interpreter.isBatchMode()) imp.repaintWindow();
return null;
} else if (name.equals("getDicomTag")) {
String value = imp.getStringProperty(getStringArg());
return new Variable(value!=null?value:"");
} else if (name.equals("setList")) {
setPropertiesFromString(imp.getImageProperties());
return null;
} else if (name.equals("getList")) {
return new Variable(getPropertiesAsString(imp.getImageProperties()));
} else
interp.error("Unrecognized Property function");
return null;
}
private void setPropertiesFromString(Properties props) {
String list = getStringArg();
props.clear();
try {
InputStream is = new ByteArrayInputStream(list.getBytes("utf-8"));
props.load(is);
} catch(Exception e) {
interp.error(""+e);
}
}
private String getPropertiesAsString(Properties props) {
interp.getParens();
Vector v = new Vector();
for (Enumeration en=props.keys(); en.hasMoreElements();)
v.addElement(en.nextElement());
String[] keys = new String[v.size()];
for (int i=0; i
© 2015 - 2024 Weber Informatics LLC | Privacy Policy