import ij.*;import ij.plugin.filter.PlugInFilter;import ij.process.*;import java.awt.*;import ij.gui.GenericDialog;/** HOCR plug-in filter - Hebrew OCR using HOCR library.A few things to note:	1) Filter plug-ins must implement the PlugInFilter interface.	2) Plug-ins located in the "plug-in" folder must not use	the package statement;	3) Plug-ins residing in the "plugins" folder and with at	least one underscore in their name will be automatically	installed in the PlugIns menu.	4) Plug-ins can be installed in other menus be editing	the ij.properties file.	5) You must edit ij.properties to get you plug-in to appear	in the Help->About PlugIns sub-menu.	6) The class name and file name must be the same.	7) This filter works with ROIs, including non-rectangular ROIs.	5) It will be called repeatedly to process all the slices in a stack.*/public class Hocr_Plugin implements PlugInFilter {  // initialize class  static  {		System.loadLibrary("hocr_java");		// to specify full path:    //   System.load("c:/path/to/dll/hocr-java.dll");		  }  /////////////////////////////////////////////////////  // options the user may edit with a dialog box  // (use static variables because program destroys the plugin object  //  after each use)  static int     brightness = 100;  static boolean do_HOCR_COMMAND_NIKUD = true; // use nikud  static boolean do_HOCR_COMMAND_USE_SPACE_FOR_TAB = true; // use spaces  static boolean do_HOCR_COMMAND_USE_INDENTATION = false; // use indentation  static boolean do_HOCR_COMMAND_DICT = false;  static boolean showParseImage = false;        /////////////////////////////////////////////////////  // constants for hocr library  private static final int HOCR_COMMAND_COLOR_BOXES = 1;  private static final int HOCR_COMMAND_COLOR_MISREAD = 2;  private static final int HOCR_COMMAND_OCR = 4;  private static final int HOCR_COMMAND_DICT = 8;  private static final int HOCR_COMMAND_NIKUD = 16;  private static final int HOCR_COMMAND_USE_SPACE_FOR_TAB = 32;  private static final int HOCR_COMMAND_USE_INDENTATION = 64;	public int setup(String arg, ImagePlus imp) {		if (arg.equals("about"))			{showAbout(); return DONE;}		return DOES_8G +  // 8-bit grayscale images.		       DOES_8C +  // 8-bit indexed color images.		       DOES_RGB + // RGB images.           DOES_STACKS + // Set this flag if the filter wants its run()                          // method to be called for all the slices in a stack.		       NO_CHANGES +  // the filter makes no changes to the pixel data.           SUPPORTS_MASKING; // for non-rectangular ROIs, ImageJ shoud restore                             // that part of the image that's inside the bounding                             // rectangle but outside of the ROI.	}	public static native String doOcr_Params(    byte[] pixels,    int height,    int width,    int rowstride, //0=calculate using n_channels,width    int n_channels, // 1,3    int brightness, //0=default    int command //0=default    );		public void run(ImageProcessor ip) {    if (!showDialog())      return;        boolean isColorImage = ip instanceof ColorProcessor;		Rectangle r = ip.getRoi();		    // create rgb array in the format hocr needs    byte[] hocr_pixels = new byte[3*r.width*r.height];    int[] tmp_pixel_val = {0xff,0xff,0xff};		int i = 0;		for (int y=r.y; y<(r.y+r.height); y++) {			for (int x=r.x; x<(r.x+r.width); x++) {        ip.getPixel(x, y, tmp_pixel_val);				hocr_pixels[i  ] = (byte)tmp_pixel_val[0];				hocr_pixels[i+1] = (byte)tmp_pixel_val[isColorImage ? 1 : 0];				hocr_pixels[i+2] = (byte)tmp_pixel_val[isColorImage ? 2 : 0];				i += 3;			}		}		    int command = HOCR_COMMAND_OCR;          if (do_HOCR_COMMAND_NIKUD)      command |= HOCR_COMMAND_NIKUD;          if (do_HOCR_COMMAND_USE_SPACE_FOR_TAB)      command |= HOCR_COMMAND_USE_SPACE_FOR_TAB;          if (do_HOCR_COMMAND_USE_INDENTATION)      command |= HOCR_COMMAND_USE_INDENTATION;          if (do_HOCR_COMMAND_DICT)      command |= HOCR_COMMAND_DICT;      if (showParseImage)      command |= HOCR_COMMAND_COLOR_BOXES | HOCR_COMMAND_COLOR_MISREAD;  		String ocr = 	doOcr_Params(        hocr_pixels,        r.height,        r.width,        0, // rowstride (0=calculate using n_channels,width)        3, // number of channels: 1,3        brightness, //0=default        command //0=default      );    //    // open new text window with ocr output    //    // ImageJ provides an excelent class to do that. single line usage:		//    ij.text.TextWindow text = new ij.text.TextWindow("OCR Result", ocr, 300, 300);		//		// However, I can't make this window display the text right-aligned,		// maybe because that window is based on awt and not on swing.		// So I create my own window (no menus and other ImageJ stuff...)    javax.swing.JFrame win = new javax.swing.JFrame();    win.setTitle("OCR Result");    win.setSize(300, 300);//    javax.swing.JTextArea textarea = new javax.swing.JTextArea();  javax.swing.JTextPane textarea = new javax.swing.JTextPane();    textarea.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);    textarea.setText(ocr);    textarea.setFont(new Font(                       textarea.getFont().getName(),                       textarea.getFont().getStyle(),                       textarea.getFont().getSize()*2));    win.getContentPane().add(new javax.swing.JScrollPane(textarea));    win.setVisible(true);		    // create a new image from the pixel data returned from hocr    if (showParseImage)    {  		ImageProcessor new_ip = new ColorProcessor(r.width, r.height);  		i = 0;  		for (int y=0; y<r.height; y++) {  			for (int x=0; x<r.width; x++) {  			  // avoid sign extention using:  & 0xFF  				tmp_pixel_val[0] = hocr_pixels[i  ] & 0xFF;  				tmp_pixel_val[1] = hocr_pixels[i+1] & 0xFF;  				tmp_pixel_val[2] = hocr_pixels[i+2] & 0xFF;          new_ip.putPixel(x, y, tmp_pixel_val);  				i += 3;  			}  		}  		new ImagePlus("OCR Parse Image", new_ip).show();		}	}  // show options dialog  boolean showDialog() {      GenericDialog gd = new GenericDialog("HOCR Setting");      gd.addNumericField("Brightness threshold:", brightness, 0);      gd.addCheckbox("Enable Nikud Detection", do_HOCR_COMMAND_NIKUD);      gd.addCheckbox("Replace TABs with spaces", do_HOCR_COMMAND_USE_SPACE_FOR_TAB);      gd.addCheckbox("Indent indented lines", do_HOCR_COMMAND_USE_INDENTATION);      gd.addCheckbox("Use internal dictionary to guess misread fonts", do_HOCR_COMMAND_DICT);      gd.addCheckbox("Display Parse Image", showParseImage);            gd.showDialog();      if (gd.wasCanceled())           return false;      brightness = (int) gd.getNextNumber();      do_HOCR_COMMAND_NIKUD = gd.getNextBoolean();      do_HOCR_COMMAND_USE_SPACE_FOR_TAB = gd.getNextBoolean();      do_HOCR_COMMAND_USE_INDENTATION = gd.getNextBoolean();      do_HOCR_COMMAND_DICT = gd.getNextBoolean();      showParseImage = gd.getNextBoolean();      return true;  }	void showAbout() {		IJ.showMessage("About Inverter_...",			"This plug-in filter does Hebrew OCR to 8-bit and RGB images,\n" +			"using the HOCR library.\n" +			"See http://hocr.berlios.de/ \n" +			""		);	}}