Re: How to validate a String to use as a macro

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Re: How to validate a String to use as a macro

Wayne Rasband-2
> On Dec 19, 2017, at 12:11 PM, Maximilian Maske <[hidden email]> wrote:
>
> Hi there,
>
> does somebody know how I can validate a String before I want to
> interpret it as a macro? I am using the Tokenizer and the Interpreter to
> parse the function, but if I input some wrong method it will just be in
> some infinite loop somewhere.
>
> The ImageJ Plugin "Process>Math>Macro..." is checking for errors. Does
> someone know how?

The Process>Math>Macro command and ImageProcessor.applyMacro() method run the macro code once at the beginning and abort if there is a syntax error. If there are no syntax errors, it applies the code to each pixel in the current image. The code that checks for errors is in the applyMacro() method of the ImageMath class, with source code at

   https://imagej.nih.gov/ij/developer/source/ij/plugin/filter/ImageMath.java.html

This JavaScript example

  ip = new FloatProcessor(1000,1000);
  t0 = System.currentTimeMillis();
  ip.applyMacro(“v=sin(d/25)");
  time = System.currentTimeMillis()-t0;
  new ImagePlus(" "+time+"ms",ip).show();

generates a macro error if you change “v=sin(d/25)” to “v=sinx(d/25)”. In the latest ImageJ daily build (1.51t17), the “v=“ in the macro code is optional. In earlier version of ImageJ, if “v=“ is missing, a number is displayed in the Log window for each pixel in the image. Check out the Help>Examples>JavaScript>Synthetic Images command in the daily build for example of how to use the ImageProcessor.applyMacro() method.

-wayne

> I am using the applyMacro() Method from ImageMath, which I adapted a
> little bit in my Program.
>
> Regards and thank you for the help,
> Max
>
> ---
> The class extents ImageMath:
>
> private void applyMacro(ImagePlus imagePlus, String macro, double[]min,
> double[]max) {
>
>        ImageProcessor ip = imagePlus.getProcessor();
>
>        double[] range = new double[min.length];
>        for (int i = 0; i < range.length; i++) {
>            range[i] = Math.abs(min[i] - max[i]);
>        }
>
>        int PCStart = 23;
>        Program pgm = (new Tokenizer()).tokenize(macro);
>        boolean hasX = pgm.hasWord("x");
>        boolean hasZ = pgm.hasWord("z");
>        boolean hasA = pgm.hasWord("a");
>        boolean hasD = pgm.hasWord("d");
>        boolean hasGetPixel = pgm.hasWord("getPixel");
>        int w = ip.getWidth();
>        int h = ip.getHeight();
>        int w2 = w/2;
>        int h2 = h/2;
>        String code =
>                "var v,x,y,z,w,h,d,a;\n"+
>                        "function dummy() {}\n"+
>                        macro+";\n"; // code starts at program counter
> location 'PCStart'
>        Interpreter interpreter = new Interpreter();
>        interpreter.run(code, null);
>        if (interpreter.wasError()) return;
>
>        Prefs.set(MACRO_KEY, macro);
>        interpreter.setVariable("w", w);
>        interpreter.setVariable("h", h);
>        interpreter.setVariable("z", ip.getSliceNumber()-1);
>        int bitDepth = ip.getBitDepth();
>        Rectangle r = ip.getRoi();
>        int inc = r.height/50;
>        if (inc<1) inc = 1;
>        int slices = imagePlus.getNSlices();
>        double v;
>        int pos, v2;
>        if (bitDepth==8) { // 8-Bit
>            byte[] pixels1 = (byte[])ip.getPixels();
>            byte[] pixels2 = pixels1;
>            if (hasGetPixel)
>                pixels2 = new byte[w*h];
>            for (int y=r.y; y<(r.y+r.height); y++) {
>                if (y%inc==0) IJ.showProgress(y-r.y, r.height);
>
>                double y_ = (double) y / h; // 0..1
>                double dy = range[1] * y_ + min[1]; // min..max
>                interpreter.setVariable("y", dy);
>
>                for (int x=r.x; x<(r.x+r.width); x++) {
>                    pos = y * w + x;
>                    v = pixels1[pos]&255;
>                    interpreter.setVariable("v", v);
>
>                    double x_ = (double) x / w; // 0..1
>                    double dx = range[1] * x_ + min[1]; // min..max
>                    if (hasX) interpreter.setVariable("x", dx);
>
>                    if (hasA) interpreter.setVariable("a",
> getA((h-y-1)-h2, x-w2));
>                    if (hasD) interpreter.setVariable("d", getD(x-w2,y-h2));
>                    interpreter.run(PCStart);
>                    v2 = (int)interpreter.getVariable("v");
>                    if (v2<0) v2 = 0;
>                    if (v2>255) v2 = 255;
>                    pixels2[pos] = (byte)v2;
>                }
>            }
>            if (hasGetPixel) System.arraycopy(pixels2, 0, pixels1, 0, w*h);
>        } else if (bitDepth==24) { // RGB
>            int rgb, red, green, blue;
>            int[] pixels1 = (int[])ip.getPixels();
>            int[] pixels2 = pixels1;
>            if (hasGetPixel)
>                pixels2 = new int[w*h];
>            for (int y=r.y; y<(r.y+r.height); y++) {
>                if (y%inc==0)
>                    IJ.showProgress(y-r.y, r.height);
>                interpreter.setVariable("y", y);
>                for (int x=r.x; x<(r.x+r.width); x++) {
>                    if (hasX) interpreter.setVariable("x", x);
>                    if (hasA) interpreter.setVariable("a",
> getA((h-y-1)-h2, x-w2));
>                    if (hasD) interpreter.setVariable("d", getD(x-w2,y-h2));
>                    pos = y*w+x;
>                    rgb = pixels1[pos];
>                    if (hasGetPixel) {
>                        interpreter.setVariable("v", rgb);
>                        interpreter.run(PCStart);
>                        rgb = (int)interpreter.getVariable("v");
>                    } else {
>                        red = (rgb&0xff0000)>>16;
>                        green = (rgb&0xff00)>>8;
>                        blue = rgb&0xff;
>                        interpreter.setVariable("v", red);
>                        interpreter.run(PCStart);
>                        red = (int)interpreter.getVariable("v");
>                        if (red<0) red=0; if (red>255) red=255;
>                        interpreter.setVariable("v", green);
>                        interpreter.run(PCStart);
>                        green= (int)interpreter.getVariable("v");
>                        if (green<0) green=0; if (green>255) green=255;
>                        interpreter.setVariable("v", blue);
>                        interpreter.run(PCStart);
>                        blue = (int)interpreter.getVariable("v");
>                        if (blue<0) blue=0; if (blue>255) blue=255;
>                        rgb = 0xff000000 | ((red&0xff)<<16) |
> ((green&0xff)<<8) | blue&0xff;
>                    }
>                    pixels2[pos] = rgb;
>                }
>            }
>            if (hasGetPixel) System.arraycopy(pixels2, 0, pixels1, 0, w*h);
>        } else if (ip.isSigned16Bit()) { //
>            for (int y=r.y; y<(r.y+r.height); y++) {
>                if (y%inc==0)
>                    IJ.showProgress(y-r.y, r.height);
>                interpreter.setVariable("y", y);
>                for (int x=r.x; x<(r.x+r.width); x++) {
>                    v = ip.getPixelValue(x, y);
>                    interpreter.setVariable("v", v);
>                    if (hasX) interpreter.setVariable("x", x);
>                    if (hasA) interpreter.setVariable("a",
> getA((h-y-1)-h2, x-w2));
>                    if (hasD) interpreter.setVariable("d", getD(x-w2,y-h2));
>                    interpreter.run(PCStart);
>                    ip.putPixelValue(x, y, interpreter.getVariable("v"));
>                }
>            }
>        } else if (bitDepth==16) {
>            short[] pixels1 = (short[])ip.getPixels();
>            short[] pixels2 = pixels1;
>            if (hasGetPixel)
>                pixels2 = new short[w*h];
>            for (int y=r.y; y<(r.y+r.height); y++) {
>                if (y%inc==0)
>                    IJ.showProgress(y-r.y, r.height);
>                interpreter.setVariable("y", y);
>                for (int x=r.x; x<(r.x+r.width); x++) {
>                    pos = y*w+x;
>                    v = pixels1[pos]&65535;
>                    interpreter.setVariable("v", v);
>                    if (hasX) interpreter.setVariable("x", x);
>                    if (hasA) interpreter.setVariable("a",
> getA((h-y-1)-h2, x-w2));
>                    if (hasD) interpreter.setVariable("d", getD(x-w2,y-h2));
>                    interpreter.run(PCStart);
>                    v2 = (int)interpreter.getVariable("v");
>                    if (v2<0) v2 = 0;
>                    if (v2>65535) v2 = 65535;
>                    pixels2[pos] = (short)v2;
>                }
>            }
>            if (hasGetPixel) System.arraycopy(pixels2, 0, pixels1, 0, w*h);
>        } else {  //32-bit
>            for(int z_=0; z_<slices; z_++) {
>                ip = imagePlus.getImageStack().getProcessor(z_ + 1);
>                double z = (double) z_ / slices; // 0..1
>                double dz = range[2] * z + min[2]; // min..max
>                if(hasZ) interpreter.setVariable("z", dz);
>
>                float[] pixels1 = (float[])ip.getPixels();
>                float[] pixels2 = pixels1;
>                if (hasGetPixel)
>                    pixels2 = new float[w*h];
>                for (int y = r.y; y < (r.y + r.height); y++) {
>                    if (y % inc == 0) IJ.showProgress(y - r.y, r.height);
>
>                    double y_ = (double) y / h; // 0..1
>                    double dy = range[1] * y_ + min[1]; // min..max
>                    interpreter.setVariable("y", dy);
>
>                    for (int x = r.x; x < (r.x + r.width); x++) {
>                        pos = y * w + x;
>                        v = pixels1[pos];
>                        interpreter.setVariable("v", v);
>
>                        double x_ = (double) x / w; // 0..1
>                        double dx = range[1] * x_ + min[1]; // min..max
>                        if (hasX) interpreter.setVariable("x", dx);
>
>                        if (hasA) interpreter.setVariable("a", getA((h -
> y - 1) - h2, x - w2));
>                        if (hasD) interpreter.setVariable("d", getD(x -
> w2, y - h2));
>                        interpreter.run(PCStart);
>                        pixels2[pos] = (float) interpreter.getVariable("v");
>                    }
>                }
>                if (hasGetPixel) System.arraycopy(pixels2, 0, pixels1,
> 0, w*h);
>            }
>        }
>        IJ.showProgress(1.0);
>    }
>
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.html

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html