├── .github ├── build.sh ├── setup.sh └── workflows │ ├── build-main.yml │ └── build-pr.yml ├── .gitignore ├── .mailmap ├── IJ_Props.txt ├── LICENSE.txt ├── MANIFEST.MF ├── README.md ├── applet.html ├── build.xml ├── compile.bat ├── functions.html ├── ij ├── CommandListener.java ├── CompositeImage.java ├── Executer.java ├── IJ.java ├── IJEventListener.java ├── ImageJ.java ├── ImageJApplet.java ├── ImageListener.java ├── ImageListenerAdapter.java ├── ImagePlus.java ├── ImageStack.java ├── LookUpTable.java ├── Macro.java ├── Menus.java ├── OtherInstance.java ├── Prefs.java ├── RecentOpener.java ├── Undo.java ├── VirtualStack.java ├── WindowManager.java ├── gui │ ├── Arrow.java │ ├── ColorChooser.java │ ├── DialogListener.java │ ├── EllipseRoi.java │ ├── FreehandRoi.java │ ├── GUI.java │ ├── GenericDialog.java │ ├── HTMLDialog.java │ ├── HistogramPlot.java │ ├── HistogramWindow.java │ ├── ImageCanvas.java │ ├── ImageLayout.java │ ├── ImagePanel.java │ ├── ImageRoi.java │ ├── ImageWindow.java │ ├── Line.java │ ├── MessageDialog.java │ ├── MultiLineLabel.java │ ├── NewImage.java │ ├── NonBlockingGenericDialog.java │ ├── OvalRoi.java │ ├── Overlay.java │ ├── Plot.java │ ├── PlotCanvas.java │ ├── PlotContentsDialog.java │ ├── PlotDialog.java │ ├── PlotMaker.java │ ├── PlotVirtualStack.java │ ├── PlotWindow.java │ ├── PointRoi.java │ ├── PolygonRoi.java │ ├── ProfilePlot.java │ ├── ProgressBar.java │ ├── Roi.java │ ├── RoiBrush.java │ ├── RoiDefaultsDialog.java │ ├── RoiListener.java │ ├── RoiProperties.java │ ├── RotatedRectRoi.java │ ├── SaveChangesDialog.java │ ├── ScrollbarWithLabel.java │ ├── ShapeRoi.java │ ├── StackWindow.java │ ├── TextRoi.java │ ├── Toolbar.java │ ├── TrimmedButton.java │ ├── WaitForUserDialog.java │ ├── Wand.java │ └── YesNoCancelDialog.java ├── io │ ├── BitBuffer.java │ ├── DirectoryChooser.java │ ├── DragAndDropHandler.java │ ├── FileInfo.java │ ├── FileOpener.java │ ├── FileSaver.java │ ├── ImageReader.java │ ├── ImageWriter.java │ ├── ImportDialog.java │ ├── LogStream.java │ ├── OpenDialog.java │ ├── Opener.java │ ├── PluginClassLoader.java │ ├── RandomAccessStream.java │ ├── RoiDecoder.java │ ├── RoiEncoder.java │ ├── SaveDialog.java │ ├── TextEncoder.java │ ├── TiffDecoder.java │ └── TiffEncoder.java ├── macro │ ├── Debugger.java │ ├── ExtensionDescriptor.java │ ├── FunctionFinder.java │ ├── Functions.java │ ├── Interpreter.java │ ├── MacroConstants.java │ ├── MacroException.java │ ├── MacroExtension.java │ ├── MacroRunner.java │ ├── Program.java │ ├── ReturnException.java │ ├── StartupRunner.java │ ├── Symbol.java │ ├── Tokenizer.java │ └── Variable.java ├── measure │ ├── Calibration.java │ ├── CurveFitter.java │ ├── Measurements.java │ ├── Minimizer.java │ ├── ResultsTable.java │ ├── ResultsTableMacros.java │ ├── SplineFitter.java │ └── UserFunction.java ├── plugin │ ├── AVI_Reader.java │ ├── AboutBox.java │ ├── Animator.java │ ├── AppearanceOptions.java │ ├── ArrowToolOptions.java │ ├── BMP_Reader.java │ ├── BMP_Writer.java │ ├── BatchConverter.java │ ├── BatchMeasure.java │ ├── BatchProcessor.java │ ├── Benchmark.java │ ├── Binner.java │ ├── BrowserLauncher.java │ ├── CalibrationBar.java │ ├── CanvasResizer.java │ ├── ChannelArranger.java │ ├── ChannelSplitter.java │ ├── CircularRoiMaker.java │ ├── ClassChecker.java │ ├── Clipboard.java │ ├── Colors.java │ ├── CommandFinder.java │ ├── CommandLister.java │ ├── Commands.java │ ├── Compiler.java │ ├── CompositeConverter.java │ ├── Concatenator.java │ ├── ContrastEnhancer.java │ ├── ControlPanel.java │ ├── Converter.java │ ├── Coordinates.java │ ├── DICOM.java │ ├── Distribution.java │ ├── DragAndDrop.java │ ├── Duplicator.java │ ├── EventListener.java │ ├── FFT.java │ ├── FFTMath.java │ ├── FITS_Reader.java │ ├── FITS_Writer.java │ ├── FileInfoVirtualStack.java │ ├── Filters3D.java │ ├── FolderOpener.java │ ├── GIF_Reader.java │ ├── GaussianBlur3D.java │ ├── GelAnalyzer.java │ ├── GifWriter.java │ ├── Grid.java │ ├── GroupedZProjector.java │ ├── Histogram.java │ ├── Hotkeys.java │ ├── HyperStackConverter.java │ ├── HyperStackMaker.java │ ├── HyperStackReducer.java │ ├── ImageCalculator.java │ ├── ImageInfo.java │ ├── ImageJ_Updater.java │ ├── ImagesToStack.java │ ├── JavaProperties.java │ ├── JavaScriptEvaluator.java │ ├── JpegWriter.java │ ├── LUT_Editor.java │ ├── ListVirtualStack.java │ ├── LutLoader.java │ ├── MacroInstaller.java │ ├── Macro_Runner.java │ ├── MeasurementsWriter.java │ ├── Memory.java │ ├── MontageMaker.java │ ├── NewPlugin.java │ ├── NextImageOpener.java │ ├── Options.java │ ├── Orthogonal_Views.java │ ├── OverlayCommands.java │ ├── OverlayLabels.java │ ├── PGM_Reader.java │ ├── PNG_Writer.java │ ├── PNM_Writer.java │ ├── PlugIn.java │ ├── PlugInInterpreter.java │ ├── PluginInstaller.java │ ├── PointToolOptions.java │ ├── Profiler.java │ ├── Projector.java │ ├── ProxySettings.java │ ├── RGBStackConverter.java │ ├── RGBStackMerge.java │ ├── RandomOvals.txt │ ├── Raw.java │ ├── RectToolOptions.java │ ├── Resizer.java │ ├── RoiEnlarger.java │ ├── RoiInterpolator.java │ ├── RoiReader.java │ ├── RoiRotator.java │ ├── RoiScaler.java │ ├── ScaleBar.java │ ├── Scaler.java │ ├── ScreenGrabber.java │ ├── Selection.java │ ├── SimpleCommands.java │ ├── Slicer.java │ ├── SpecifyROI.java │ ├── StackCombiner.java │ ├── StackEditor.java │ ├── StackInserter.java │ ├── StackMaker.java │ ├── StackPlotter.java │ ├── StackReducer.java │ ├── StackReverser.java │ ├── StackWriter.java │ ├── Stack_Statistics.java │ ├── Startup.java │ ├── Straightener.java │ ├── SubHyperstackMaker.java │ ├── SubstackMaker.java │ ├── SurfacePlotter.java │ ├── Text.java │ ├── TextFileReader.java │ ├── TextReader.java │ ├── TextWriter.java │ ├── ThreadLister.java │ ├── Thresholder.java │ ├── URLOpener.java │ ├── WandToolOptions.java │ ├── WindowOrganizer.java │ ├── XYCoordinates.java │ ├── XY_Reader.java │ ├── ZAxisProfiler.java │ ├── ZProjector.java │ ├── Zoom.java │ ├── filter │ │ ├── AVI_Writer.java │ │ ├── Analyzer.java │ │ ├── BackgroundSubtracter.java │ │ ├── Benchmark.java │ │ ├── Binary.java │ │ ├── Calibrator.java │ │ ├── Convolver.java │ │ ├── Duplicater.java │ │ ├── EDM.java │ │ ├── ExtendedPlugInFilter.java │ │ ├── FFTCustomFilter.java │ │ ├── FFTFilter.java │ │ ├── Filler.java │ │ ├── Filters.java │ │ ├── FractalBoxCounter.java │ │ ├── GaussianBlur.java │ │ ├── ImageMath.java │ │ ├── ImageProperties.java │ │ ├── Info.java │ │ ├── LineGraphAnalyzer.java │ │ ├── LutApplier.java │ │ ├── LutViewer.java │ │ ├── MaximumFinder.java │ │ ├── ParticleAnalyzer.java │ │ ├── PlugInFilter.java │ │ ├── PlugInFilterRunner.java │ │ ├── Printer.java │ │ ├── RGBStackSplitter.java │ │ ├── RankFilters.java │ │ ├── RoiWriter.java │ │ ├── Rotator.java │ │ ├── SaltAndPepper.java │ │ ├── ScaleDialog.java │ │ ├── Shadows.java │ │ ├── StackLabeler.java │ │ ├── ThresholdToSelection.java │ │ ├── Transformer.java │ │ ├── Translator.java │ │ ├── UnsharpMask.java │ │ ├── Writer.java │ │ └── XYWriter.java │ ├── frame │ │ ├── Channels.java │ │ ├── ColorPicker.java │ │ ├── ColorThresholder.java │ │ ├── Commands.java │ │ ├── ContrastAdjuster.java │ │ ├── Editor.java │ │ ├── Fitter.java │ │ ├── LineWidthAdjuster.java │ │ ├── MemoryMonitor.java │ │ ├── PasteController.java │ │ ├── PlugInDialog.java │ │ ├── PlugInFrame.java │ │ ├── Recorder.java │ │ ├── RoiManager.java │ │ ├── SyncWindows.java │ │ └── ThresholdAdjuster.java │ └── tool │ │ ├── ArrowTool.java │ │ ├── BrushTool.java │ │ ├── MacroToolRunner.java │ │ ├── OverlayBrushTool.java │ │ ├── PixelInspectionTool.java │ │ ├── PlugInTool.java │ │ └── RoiRotationTool.java ├── process │ ├── AutoThresholder.java │ ├── BinaryInterpolator.java │ ├── BinaryProcessor.java │ ├── Blitter.java │ ├── ByteBlitter.java │ ├── ByteProcessor.java │ ├── ByteStatistics.java │ ├── ColorBlitter.java │ ├── ColorProcessor.java │ ├── ColorSpaceConverter.java │ ├── ColorStatistics.java │ ├── DownsizeTable.java │ ├── EllipseFitter.java │ ├── FHT.java │ ├── FloatBlitter.java │ ├── FloatPolygon.java │ ├── FloatProcessor.java │ ├── FloatStatistics.java │ ├── FloodFiller.java │ ├── ImageConverter.java │ ├── ImageProcessor.java │ ├── ImageStatistics.java │ ├── IntProcessor.java │ ├── LUT.java │ ├── MedianCut.java │ ├── PolygonFiller.java │ ├── ShortBlitter.java │ ├── ShortProcessor.java │ ├── ShortStatistics.java │ ├── StackConverter.java │ ├── StackProcessor.java │ ├── StackStatistics.java │ └── TypeConverter.java ├── text │ ├── TextCanvas.java │ ├── TextPanel.java │ └── TextWindow.java └── util │ ├── ArrayUtil.java │ ├── DicomTools.java │ ├── FloatArray.java │ ├── FontUtil.java │ ├── IJMath.java │ ├── Java2.java │ ├── StringSorter.java │ ├── ThreadUtil.java │ ├── Tools.java │ └── WildcardMatch.java ├── images ├── about.jpg └── microscope.gif ├── macros ├── AddParticles.txt ├── Circle_Tool.txt ├── CommandFinderTool.txt ├── ConvertStackToBinary.txt ├── DeveloperMenuTool.txt ├── Filter_Plugin.src ├── FloodFillTool.txt ├── InvertAllLuts.txt ├── LUTMenuTool.txt ├── Label_Tool.txt ├── MagicMontageTools.txt ├── MeasureStack.txt ├── MoveSelection.txt ├── My_Plugin.src ├── Overlay Editing Tools.txt ├── Plugin_Frame.src ├── Prototype_Tool.src ├── RoiMenuTool.txt ├── Search.txt ├── ShowAllLuts.txt ├── SmoothWandTool.txt ├── SprayCanTool.txt ├── StacksMenuTool.txt ├── StartupMacros.txt └── TimeStamp.ijm ├── module-info.java ├── nbproject ├── build-impl.xml ├── genfiles.properties ├── project.properties └── project.xml ├── plugins ├── MacAdapter.class ├── MacAdapter.source ├── MacAdapter9.class └── MacAdapter9.source ├── policy ├── pom.xml ├── release-notes.html ├── run_appletviewer.bat └── tests ├── data ├── 01.dcm ├── BasicTable.txt ├── BogusTable.txt ├── CardioShort.raw ├── Cell_Colony.jpg ├── EmptyFile.txt ├── Tree_Rings.pgm ├── bat-cochlea-renderings.fits ├── blobs.gif ├── clown.raw ├── embryos.bmp ├── fake.gz ├── gray16-3x2-sub1.tif ├── gray16-3x2-sub2.tif ├── gray16.zip ├── gray16signedA.tif ├── gray16signedB.tif ├── gray24-3x2-sub1.tif ├── gray24-3x2-sub2.tif ├── gray32float-3x2-sub1.tif ├── gray32float-3x2-sub2.tif ├── gray8-3x2-stack.tif ├── gray8-3x2-sub1.tif ├── gray8-3x2-sub2.tif ├── head.tif ├── head8bit.tif ├── htm_symb_rep.raw └── lena-std.png └── ij ├── Assert.java ├── ByteCreator.java ├── CommandListenerTest.java ├── CompositeImageTest.java ├── ExecuterTest.java ├── IJEventListenerTest.java ├── IJInfo.java ├── ImageListenerTest.java ├── ImagePlusTest.java ├── ImageStackTest.java ├── LookUpTableTest.java ├── UndoTest.java ├── VirtualStackTest.java ├── gui ├── ArrowTest.java ├── FreehandRoiTest.java ├── ImageRoiTest.java ├── LineTest.java ├── OvalRoiTest.java ├── OverlayTest.java ├── PlotTest.java ├── PointRoiTest.java ├── PolygonRoiTest.java ├── ProfilePlotTest.java ├── ProgressBarTest.java ├── RoiHelpers.java ├── RoiTest.java ├── ShapeRoiTest.java ├── TextRoiTest.java ├── ToolbarTest.java ├── TrimmedButtonTest.java └── WandTest.java ├── io ├── AbgrFormat.java ├── ArgbFormat.java ├── BargFormat.java ├── BgrFormat.java ├── BitBufferTest.java ├── BitmapFormat.java ├── ByteOrder.java ├── Color8Format.java ├── DirectoryChooserTest.java ├── FileInfoTest.java ├── FileOpenerTest.java ├── Gray12UnsignedFormat.java ├── Gray16SignedFormat.java ├── Gray16UnsignedFormat.java ├── Gray24UnsignedFormat.java ├── Gray32FloatFormat.java ├── Gray32IntFormat.java ├── Gray32UnsignedFormat.java ├── Gray64FloatFormat.java ├── Gray8Format.java ├── ImageReaderTest.java ├── ImageWriterTest.java ├── Images.java ├── JpegEncoder.java ├── LzwDiffEncoder.java ├── LzwEncoder.java ├── PackbitsEncoder.java ├── PackbitsEncoderNaive.java ├── PixelArranger.java ├── PixelFormat.java ├── RandomAccessStreamTest.java ├── Rgb48Format.java ├── Rgb48PlanarFormat.java ├── RgbFormat.java ├── RgbPlanarFormat.java └── TwelveBitEncoder.java ├── macro ├── ReturnExceptionTest.java └── SymbolTest.java ├── measure ├── CalibrationTest.java ├── CalibrationTools.java ├── CurveFitterTest.java ├── MeasurementsTest.java ├── ResultsTableTest.java └── SplineFitterTest.java ├── process ├── BinaryProcessorTest.java ├── ByteProcessorTest.java ├── ColorProcessorTest.java ├── DataConstants.java ├── FloatProcessorTest.java ├── ImageProcessorTest.java ├── LUTTest.java └── ShortProcessorTest.java └── util ├── StringSorterTest.java └── ToolsTest.java /.github/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | curl -fsLO https://raw.githubusercontent.com/scijava/scijava-scripts/main/ci-build.sh && 3 | sh ci-build.sh && { 4 | die() { echo "[ERROR] $1"; exit 1; } 5 | 6 | echo 7 | echo "== Extracting ImageJ version from source code ==" 8 | version=$(grep -o ' VERSION *= *"[^"]*' ij/ImageJ.java) || 9 | die "Failed to extract version from ij/ImageJ.java" 10 | build=$(grep -o ' BUILD *= *"[^"]*' ij/ImageJ.java) || 11 | die "Failed to extract build number from ij/ImageJ.java" 12 | version=${version#*\"} 13 | build=${build#*\"} 14 | echo "VERSION = $version" 15 | echo "BUILD = $build" 16 | 17 | if [ "$build" = "" ] 18 | then 19 | # Sanity checks. 20 | test "$version" || die "Empty version string!" 21 | echo "$version" | grep -q '^[0-9]\+\.[0-9]\+[a-z]$' || 22 | die "Unexpected format for version string $version" 23 | 24 | echo 25 | echo "== Releasing ImageJ v$version ==" 26 | 27 | # Tweak the Maven POM to reflect the release version. 28 | cat pom.xml | sed -e "s/1\.x-SNAPSHOT/$version/" -e "s/HEADv$version pom.new && 29 | mv -f pom.new pom.xml || 30 | die "Failed to adjust pom.xml to match release version $version" 31 | 32 | # Deploy the release. 33 | mvn -Psonatype-oss-release -B -Djdk.tls.client.protocols="TLSv1,TLSv1.1,TLSv1.2" deploy 34 | else 35 | echo 36 | echo "== Skipping release for daily build $version$build ==" 37 | fi 38 | } 39 | -------------------------------------------------------------------------------- /.github/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | curl -fsLO https://raw.githubusercontent.com/scijava/scijava-scripts/main/ci-setup-github-actions.sh 3 | sh ci-setup-github-actions.sh 4 | -------------------------------------------------------------------------------- /.github/workflows/build-main.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | tags: 8 | - "*-[0-9]+.*" 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v2 16 | - name: Set up Java 17 | uses: actions/setup-java@v2 18 | with: 19 | java-version: '11' 20 | distribution: 'zulu' 21 | cache: 'maven' 22 | - name: Set up CI environment 23 | run: .github/setup.sh 24 | - name: Execute the build 25 | run: .github/build.sh 26 | env: 27 | GPG_KEY_NAME: ${{ secrets.GPG_KEY_NAME }} 28 | GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} 29 | MAVEN_USER: ${{ secrets.MAVEN_USER }} 30 | MAVEN_PASS: ${{ secrets.MAVEN_PASS }} 31 | OSSRH_PASS: ${{ secrets.OSSRH_PASS }} 32 | SIGNING_ASC: ${{ secrets.SIGNING_ASC }} 33 | -------------------------------------------------------------------------------- /.github/workflows/build-pr.yml: -------------------------------------------------------------------------------- 1 | name: build PR 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - uses: actions/checkout@v2 14 | - name: Set up Java 15 | uses: actions/setup-java@v2 16 | with: 17 | java-version: '11' 18 | distribution: 'zulu' 19 | cache: 'maven' 20 | - name: Set up CI environment 21 | run: .github/setup.sh 22 | - name: Execute the build 23 | run: .github/build.sh 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *~ 3 | 4 | # Builds 5 | *.class 6 | /*.jar 7 | /build/ 8 | /target/ 9 | 10 | # Eclipse 11 | /.classpath 12 | /.project 13 | /.settings/ 14 | 15 | # IntelliJ IDEA 16 | /.idea/ 17 | -------------------------------------------------------------------------------- /.mailmap: -------------------------------------------------------------------------------- 1 | Wayne Rasband 2 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | ImageJ Disclaimer 2 | 3 | ImageJ was developed at the National Institutes of Health by an employee of the 4 | Federal Government in the course of his official duties. Pursuant to Title 17, 5 | Section 105 of the United States Code, this software is not subject to 6 | copyright protection and is in the public domain. ImageJ is an experimental 7 | system. NIH assumes no responsibility whatsoever for its use by other parties, 8 | and makes no guarantees, expressed or implied, about its quality, reliability, 9 | or any other characteristic. 10 | -------------------------------------------------------------------------------- /MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Main-Class: ij.ImageJ 2 | 3 | -------------------------------------------------------------------------------- /applet.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ImageJ Applet 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /compile.bat: -------------------------------------------------------------------------------- 1 | javac ij\ImageJ.java 2 | javac ij\plugin\*.java 3 | javac ij\plugin\filter\*.java 4 | javac ij\plugin\frame\*.java 5 | java ij.ImageJ 6 | -------------------------------------------------------------------------------- /ij/CommandListener.java: -------------------------------------------------------------------------------- 1 | package ij; 2 | 3 | /** Plugins that implement this interface are notified when ImageJ 4 | is about to run a menu command. There is an example plugin at 5 | http://imagej.net/ij/plugins/download/misc/Command_Listener.java 6 | */ 7 | public interface CommandListener { 8 | 9 | /* The method is called when ImageJ is about to run a menu command, 10 | where 'command' is the name of the command. Return this string 11 | and ImageJ will run the command, return a different command name 12 | and ImageJ will run that command, or return null to not run a command. 13 | */ 14 | public String commandExecuting(String command); 15 | 16 | } 17 | -------------------------------------------------------------------------------- /ij/IJEventListener.java: -------------------------------------------------------------------------------- 1 | package ij; 2 | 3 | /** Plugins that implement this interface are notified when the user 4 | changes the foreground color, changes the background color, 5 | closes the color picker, closes the Log window or switches to 6 | another tool. 7 | */ 8 | public interface IJEventListener { 9 | public static final int FOREGROUND_COLOR_CHANGED = 0; 10 | public static final int BACKGROUND_COLOR_CHANGED = 1; 11 | public static final int COLOR_PICKER_CLOSED= 2; 12 | public static final int LOG_WINDOW_CLOSED= 3; 13 | public static final int TOOL_CHANGED= 4; 14 | 15 | public void eventOccurred(int eventID); 16 | 17 | } 18 | -------------------------------------------------------------------------------- /ij/ImageJApplet.java: -------------------------------------------------------------------------------- 1 | package ij; 2 | import java.applet.Applet; 3 | 4 | /** 5 | Runs ImageJ as an applet and optionally opens up to 6 | nine images using URLs passed as a parameters. 7 |

8 | Here is an example applet tag that launches ImageJ as an applet 9 | and passes it the URLs of two images: 10 |

11 | 	<applet archive="../ij.jar" code="ij.ImageJApplet.class" width=0 height=0>
12 | 	<param name=url1 value="http://imagej.nih.gov/ij/images/FluorescentCells.jpg">
13 | 	<param name=url2 value="http://imagej.nih.gov/ij/images/blobs.gif">
14 | 	</applet>
15 | 	
16 | To use plugins, add them to ij.jar and add entries to IJ_Props.txt file (in ij.jar) that will 17 | create commands for them in the Plugins menu, or a submenu. There are examples 18 | of such entries in IJ.Props.txt, in the "Plugins installed in the Plugins menu" section. 19 |

20 | Macros contained in a file named "StartupMacros.txt", in the same directory as the HTML file 21 | containing the applet tag, will be installed on startup. 22 | */ 23 | public class ImageJApplet extends Applet { 24 | 25 | /** Starts ImageJ if it's not already running. */ 26 | public void init() { 27 | ImageJ ij = IJ.getInstance(); 28 | if (ij==null || (ij!=null && !ij.isShowing())) 29 | new ImageJ(this); 30 | for (int i=1; i<=9; i++) { 31 | String url = getParameter("url"+i); 32 | if (url==null) break; 33 | ImagePlus imp = new ImagePlus(url); 34 | if (imp!=null) imp.show(); 35 | } 36 | } 37 | 38 | public void destroy() { 39 | ImageJ ij = IJ.getInstance(); 40 | if (ij!=null) ij.quit(); 41 | } 42 | 43 | } 44 | 45 | -------------------------------------------------------------------------------- /ij/ImageListener.java: -------------------------------------------------------------------------------- 1 | package ij; 2 | 3 | /** Plugins that implement this interface are notified when 4 | an image is opened, closed or updated. The 5 | Plugins/Utilities/Monitor Events command uses this interface. 6 | */ 7 | public interface ImageListener { 8 | 9 | public void imageOpened(ImagePlus imp); 10 | 11 | public void imageClosed(ImagePlus imp); 12 | 13 | public void imageUpdated(ImagePlus imp); 14 | 15 | //default void imageSaved(ImagePlus imp) { } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /ij/ImageListenerAdapter.java: -------------------------------------------------------------------------------- 1 | package ij; 2 | 3 | /** 4 | * An Adapter class for the ImageListener interface. Note ImageListenerAdapter 5 | * supports notification when an ImagePlus gets saved. 6 | *

7 | * With this adapter you need only override the methods that you require 8 | * notification for. 9 | *

10 | * TODO When ImageJ has a minimum support of Java8 consider updating 11 | * ImageListener to provide default methods for all these callbacks as this will 12 | * allow ImageListener interface to be used as mix-in class whereas Java single 13 | * inheritance precludes that for this ImageListenerAdapter class. 14 | * 15 | * @author Michael Ellis 16 | */ 17 | public class ImageListenerAdapter implements ImageListener { 18 | 19 | @Override 20 | public void imageOpened(ImagePlus imp) { 21 | } 22 | 23 | @Override 24 | public void imageClosed(ImagePlus imp) { 25 | } 26 | 27 | @Override 28 | public void imageUpdated(ImagePlus imp) { 29 | } 30 | 31 | public void imageSaved(ImagePlus imp) { 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /ij/RecentOpener.java: -------------------------------------------------------------------------------- 1 | package ij; 2 | import ij.io.*; 3 | import java.awt.*; 4 | import java.io.*; 5 | 6 | /** Opens, in a separate thread, files selected from the File/Open Recent submenu.*/ 7 | public class RecentOpener implements Runnable { 8 | private String path; 9 | 10 | RecentOpener(String path) { 11 | this.path = path; 12 | Thread thread = new Thread(this, "RecentOpener"); 13 | thread.start(); 14 | } 15 | 16 | /** Open the file and move the path to top of the submenu. */ 17 | public void run() { 18 | Opener o = new Opener(); 19 | o.open(path); 20 | Menu menu = Menus.getOpenRecentMenu(); 21 | int n = menu.getItemCount(); 22 | int index = 0; 23 | for (int i=0; i0) { 30 | MenuItem item = menu.getItem(index); 31 | menu.remove(index); 32 | menu.insert(item, 0); 33 | } 34 | } 35 | 36 | } 37 | 38 | -------------------------------------------------------------------------------- /ij/gui/DialogListener.java: -------------------------------------------------------------------------------- 1 | package ij.gui; 2 | import ij.*; 3 | import java.awt.AWTEvent; 4 | 5 | /** 6 | * PlugIns or PlugInFilters that want to listen to changes in a GenericDialog 7 | * without adding listeners for each dialog field should implementthis method. 8 | * The dialogItemChanged method of a PlugIn or PlugInFilter can and should read 9 | * the various dialog items by the appropriate GenericDialog methods like 10 | * getNextNumber (items that are not read in the dialogItemChanged method will 11 | * not be recorded by the Macro recorder). 12 | * 13 | * The PlugIn or PlugInFilter has to be added to the GenericDialog by 14 | * its addDialogListener method: 15 | * gd.addDialogListener(this); 16 | * 17 | */ 18 | public interface DialogListener { 19 | 20 | /** 21 | * This method is invoked by a Generic Dialog if any of the inputs have changed 22 | * (CANCEL does not trigger it; OK and running the dialog from a macro only 23 | * trigger the first DialogListener added to a GenericDialog). 24 | * 25 | * @param e The event that has been generated by the user action in the dialog. 26 | * Note that e is null if the 27 | * dialogItemChanged method is called after the user has pressed the 28 | * OK button or if the GenericDialog has read its parameters from a 29 | * macro. 30 | * @param gd A reference to the GenericDialog. 31 | * @return Should be true if the dialog input is valid. False disables the 32 | * OK button and preview (if any). 33 | */ 34 | boolean dialogItemChanged(GenericDialog gd, AWTEvent e); 35 | } 36 | -------------------------------------------------------------------------------- /ij/gui/FreehandRoi.java: -------------------------------------------------------------------------------- 1 | package ij.gui; 2 | 3 | import java.awt.*; 4 | import java.awt.image.*; 5 | import ij.*; 6 | 7 | /** Freehand region of interest or freehand line of interest*/ 8 | public class FreehandRoi extends PolygonRoi { 9 | 10 | public FreehandRoi(int sx, int sy, ImagePlus imp) { 11 | super(sx, sy, imp); 12 | if (Toolbar.getToolId()==Toolbar.FREEROI) 13 | type = FREEROI; 14 | else 15 | type = FREELINE; 16 | if (nPoints==2) nPoints--; 17 | } 18 | 19 | protected void grow(int sx, int sy) { 20 | if (subPixelResolution() && xpf!=null) { 21 | growFloat(sx, sy); 22 | return; 23 | } 24 | int ox = offScreenX(sx); 25 | int oy = offScreenY(sy); 26 | if (ox<0) ox = 0; 27 | if (oy<0) oy = 0; 28 | if (ox>xMax) ox = xMax; 29 | if (oy>yMax) oy = yMax; 30 | if (ox!=xp[nPoints-1]+x || oy!=yp[nPoints-1]+y) { 31 | xp[nPoints] = ox-x; 32 | yp[nPoints] = oy-y; 33 | nPoints++; 34 | if (IJ.altKeyDown()) 35 | wipeBack(); 36 | if (nPoints==xp.length) 37 | enlargeArrays(); 38 | drawLine(); 39 | } 40 | } 41 | 42 | private void growFloat(int sx, int sy) { 43 | double ox = offScreenXD(sx); 44 | double oy = offScreenYD(sy); 45 | if (ox<0.0) ox = 0.0; 46 | if (oy<0.0) oy = 0.0; 47 | if (ox>xMax) ox = xMax; 48 | if (oy>yMax) oy = yMax; 49 | double xbase = getXBase(); 50 | double ybase = getYBase(); 51 | if (ox!=xpf[nPoints-1]+xbase || oy!=ypf[nPoints-1]+ybase) { 52 | xpf[nPoints] = (float)(ox-xbase); 53 | ypf[nPoints] = (float)(oy-ybase); 54 | nPoints++; 55 | if (nPoints==xpf.length) 56 | enlargeArrays(); 57 | drawLine(); 58 | } 59 | } 60 | 61 | void drawLine() { 62 | int x1, y1, x2, y2; 63 | if (xpf!=null) { 64 | x1 = (int)Math.round(xpf[nPoints-2]+x); 65 | y1 = (int)Math.round(ypf[nPoints-2]+y); 66 | x2 = (int)Math.round(xpf[nPoints-1]+x); 67 | y2 = (int)Math.round(ypf[nPoints-1]+y); 68 | } else { 69 | x1 = xp[nPoints-2]+x; 70 | y1 = yp[nPoints-2]+y; 71 | x2 = xp[nPoints-1]+x; 72 | y2 = yp[nPoints-1]+y; 73 | } 74 | int xmin = Math.min(x1, x2); 75 | int xmax = Math.max(x1, x2); 76 | int ymin = Math.min(y1, y2); 77 | int ymax = Math.max(y1, y2); 78 | int margin = 4; 79 | if (lineWidth>margin && isLine()) 80 | margin = lineWidth; 81 | if (ic!=null) { 82 | double mag = ic.getMagnification(); 83 | if (mag<1.0) margin = (int)(margin/mag); 84 | } 85 | if (IJ.altKeyDown()) 86 | margin += 20; // for wipeBack 87 | imp.draw(xmin-margin, ymin-margin, (xmax-xmin)+margin*2, (ymax-ymin)+margin*2); 88 | } 89 | 90 | protected void handleMouseUp(int screenX, int screenY) { 91 | if (state==CONSTRUCTING) { 92 | addOffset(); 93 | finishPolygon(); 94 | } 95 | state = NORMAL; 96 | } 97 | 98 | } 99 | -------------------------------------------------------------------------------- /ij/gui/ImagePanel.java: -------------------------------------------------------------------------------- 1 | package ij.gui; 2 | import java.awt.*; 3 | import ij.*; 4 | 5 | /** This class is used by GenericDialog to add images to dialogs. */ 6 | public class ImagePanel extends Panel { 7 | private ImagePlus img; 8 | 9 | public ImagePanel(ImagePlus img) { 10 | this.img = img; 11 | } 12 | 13 | public Dimension getPreferredSize() { 14 | return new Dimension(img.getWidth(), img.getHeight()); 15 | } 16 | 17 | public Dimension getMinimumSize() { 18 | return new Dimension(img.getWidth(), img.getHeight()); 19 | } 20 | 21 | public void paint(Graphics g) { 22 | g.drawImage(img.getProcessor().createImage(), 0, 0, null); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /ij/gui/MessageDialog.java: -------------------------------------------------------------------------------- 1 | package ij.gui; 2 | import ij.*; 3 | import java.awt.*; 4 | import java.awt.event.*; 5 | 6 | /** A modal dialog box that displays information. Based on the 7 | InfoDialogclass from "Java in a Nutshell" by David Flanagan. */ 8 | public class MessageDialog extends Dialog implements ActionListener, KeyListener, WindowListener { 9 | protected Button button; 10 | protected MultiLineLabel label; 11 | private boolean escapePressed; 12 | 13 | public MessageDialog(Frame parent, String title, String message) { 14 | super(parent, title, true); 15 | setLayout(new BorderLayout()); 16 | if (message==null) message = ""; 17 | Font font = null; 18 | double scale = Prefs.getGuiScale(); 19 | if (scale>1.0) { 20 | font = getFont(); 21 | if (font!=null) 22 | font = font.deriveFont((float)(font.getSize()*scale)); 23 | else 24 | font = new Font("SansSerif", Font.PLAIN, (int)(12*scale)); 25 | setFont(font); 26 | } 27 | label = new MultiLineLabel(message); 28 | if (font!=null) 29 | label.setFont(font); 30 | else if (!IJ.isLinux()) 31 | label.setFont(ImageJ.SansSerif14); 32 | Panel panel = new Panel(); 33 | panel.setLayout(new FlowLayout(FlowLayout.CENTER, 15, 15)); 34 | panel.add(label); 35 | add("Center", panel); 36 | button = new Button(" OK "); 37 | button.addActionListener(this); 38 | button.addKeyListener(this); 39 | panel = new Panel(); 40 | panel.setLayout(new FlowLayout()); 41 | panel.add(button); 42 | add("South", panel); 43 | if (ij.IJ.isMacintosh()) 44 | setResizable(false); 45 | pack(); 46 | GUI.centerOnImageJScreen(this); 47 | addWindowListener(this); 48 | show(); 49 | } 50 | 51 | public void actionPerformed(ActionEvent e) { 52 | dispose(); 53 | } 54 | 55 | public void keyPressed(KeyEvent e) { 56 | int keyCode = e.getKeyCode(); 57 | IJ.setKeyDown(keyCode); 58 | escapePressed = keyCode==KeyEvent.VK_ESCAPE; 59 | if (keyCode==KeyEvent.VK_ENTER || escapePressed) 60 | dispose(); 61 | } 62 | 63 | public void keyReleased(KeyEvent e) { 64 | int keyCode = e.getKeyCode(); 65 | IJ.setKeyUp(keyCode); 66 | } 67 | 68 | public void keyTyped(KeyEvent e) {} 69 | 70 | public void windowClosing(WindowEvent e) { 71 | dispose(); 72 | } 73 | 74 | public boolean escapePressed() { 75 | return escapePressed; 76 | } 77 | 78 | public void windowActivated(WindowEvent e) {} 79 | public void windowOpened(WindowEvent e) {} 80 | public void windowClosed(WindowEvent e) {} 81 | public void windowIconified(WindowEvent e) {} 82 | public void windowDeiconified(WindowEvent e) {} 83 | public void windowDeactivated(WindowEvent e) {} 84 | 85 | } 86 | -------------------------------------------------------------------------------- /ij/gui/PlotMaker.java: -------------------------------------------------------------------------------- 1 | package ij.gui; 2 | import ij.ImagePlus; 3 | 4 | /** Plugins that generate "Live" profile plots (Profiler and ZAxisProfiler) 5 | displayed in PlotWindows implement this interface. */ 6 | public interface PlotMaker { 7 | 8 | /** Returns a profile plot. */ 9 | public Plot getPlot(); 10 | 11 | /** Returns the ImagePlus used to generate the profile plots. */ 12 | public ImagePlus getSourceImage(); 13 | 14 | } 15 | 16 | -------------------------------------------------------------------------------- /ij/gui/PlotVirtualStack.java: -------------------------------------------------------------------------------- 1 | package ij.gui; 2 | import ij.*; 3 | import ij.process.*; 4 | import java.util.*; 5 | import java.io.*; 6 | 7 | /** This is a virtual stack of frozen plots. */ 8 | public class PlotVirtualStack extends VirtualStack { 9 | private Vector plots = new Vector(50); 10 | private int bitDepth = 8; 11 | 12 | public PlotVirtualStack(int width, int height) { 13 | super(width, height); 14 | } 15 | 16 | /** Adds a plot to the end of the stack. */ 17 | public void addPlot(Plot plot) { 18 | plots.add(plot.toByteArray()); 19 | if (plot.isColored()) 20 | bitDepth = 24; 21 | } 22 | 23 | /** Returns the pixel array for the specified slice, where {@literal 1<=n<=nslices}. */ 24 | public Object getPixels(int n) { 25 | ImageProcessor ip = getProcessor(n); 26 | if (ip!=null) 27 | return ip.getPixels(); 28 | else 29 | return null; 30 | } 31 | 32 | /** Returns an ImageProcessor for the specified slice, 33 | where {@literal 1<=n<=nslices}. Returns null if the stack is empty. */ 34 | public ImageProcessor getProcessor(int n) { 35 | byte[] bytes = (byte[])plots.get(n-1); 36 | if (bytes!=null) { 37 | try { 38 | Plot plot = new Plot(null, new ByteArrayInputStream(bytes)); 39 | ImageProcessor ip = plot.getProcessor(); 40 | if (bitDepth==24) 41 | ip = ip.convertToRGB(); 42 | else if (bitDepth==8) 43 | ip = ip.convertToByte(false); 44 | ip.setSliceNumber(n); 45 | return ip; 46 | } catch (Exception e) { 47 | IJ.handleException(e); 48 | } 49 | } 50 | return null; 51 | } 52 | 53 | /** Returns the number of slices in this stack. */ 54 | public int getSize() { 55 | return plots.size(); 56 | } 57 | 58 | /** Returns either 24 (RGB) or 8 (grayscale). */ 59 | public int getBitDepth() { 60 | return bitDepth; 61 | } 62 | 63 | public void setBitDepth(int bitDepth) { 64 | this.bitDepth = bitDepth; 65 | } 66 | 67 | public String getSliceLabel(int n) { 68 | return null; 69 | } 70 | 71 | public void setPixels(Object pixels, int n) { 72 | } 73 | 74 | /** Deletes the specified slice, where {@literal 1<=n<=nslices}. */ 75 | public void deleteSlice(int n) { 76 | if (n<1 || n>plots.size()) 77 | throw new IllegalArgumentException("Argument out of range: "+n); 78 | if (plots.size()<1) 79 | return; 80 | plots.remove(n-1); 81 | } 82 | 83 | 84 | } // PlotVirtualStack 85 | 86 | -------------------------------------------------------------------------------- /ij/gui/RoiBrush.java: -------------------------------------------------------------------------------- 1 | package ij.gui; 2 | import ij.*; 3 | import java.awt.*; 4 | 5 | /** Implements the ROI Brush tool.*/ 6 | class RoiBrush implements Runnable { 7 | static int ADD=0, SUBTRACT=1; 8 | static int leftClick=16, alt=9, shift=1; 9 | private Polygon poly; 10 | private Point previousP; 11 | private int mode = ADD; 12 | 13 | RoiBrush() { 14 | Thread thread = new Thread(this, "RoiBrush"); 15 | thread.start(); 16 | } 17 | 18 | public void run() { 19 | int size = Toolbar.getBrushSize(); 20 | ImagePlus img = WindowManager.getCurrentImage(); 21 | if (img==null) return; 22 | ImageCanvas ic = img.getCanvas(); 23 | if (ic==null) return; 24 | Roi roi = img.getRoi(); 25 | if (roi!=null && !roi.isArea()) 26 | img.deleteRoi(); 27 | Point p = ic.getCursorLoc(); 28 | if (roi!=null && !roi.contains(p.x, p.y)) 29 | mode = SUBTRACT; 30 | int flags; 31 | while (true) { 32 | p = ic.getCursorLoc(); 33 | if (p.equals(previousP)) 34 | {IJ.wait(1); continue;} 35 | previousP = p; 36 | flags = ic.getModifiers(); 37 | if ((flags&leftClick)==0) return; 38 | if ((flags&shift)!=0) 39 | mode = ADD; 40 | else if ((flags&alt)!=0) 41 | mode = SUBTRACT; 42 | if (mode==ADD) 43 | addCircle(img, p.x, p.y, size); 44 | else 45 | subtractCircle(img, p.x, p.y, size); 46 | } 47 | } 48 | 49 | void addCircle(ImagePlus img, int x, int y, int width) { 50 | Roi roi = img.getRoi(); 51 | Roi roi2 = roi; 52 | if (roi2!=null) { 53 | if (!(roi2 instanceof ShapeRoi)) 54 | roi2 = new ShapeRoi(roi2); 55 | ((ShapeRoi)roi2).or(getCircularRoi(x, y, width)); 56 | roi2.copyAttributes(roi); 57 | } else 58 | roi2 = new OvalRoi(x-width/2, y-width/2, width, width); 59 | img.setRoi(roi2); 60 | } 61 | 62 | void subtractCircle(ImagePlus img, int x, int y, int width) { 63 | Roi roi = img.getRoi(); 64 | Roi roi2 = roi; 65 | if (roi2!=null) { 66 | if (!(roi2 instanceof ShapeRoi)) 67 | roi2 = new ShapeRoi(roi2); 68 | ((ShapeRoi)roi2).not(getCircularRoi(x, y, width)); 69 | roi2.copyAttributes(roi); 70 | img.setRoi(roi2); 71 | } 72 | } 73 | 74 | 75 | ShapeRoi getCircularRoi(int x, int y, int width) { 76 | if (poly==null) { 77 | Roi roi = new OvalRoi(x-width/2, y-width/2, width, width); 78 | poly = roi.getPolygon(); 79 | for (int i=0; i0", null, Color.gray); 31 | gd.addDialogListener(this); 32 | gd.showDialog(); 33 | if (gd.wasCanceled()) { 34 | Roi.setGroupNames(groupNames); 35 | Roi.setColor(color); 36 | Roi.setDefaultStrokeWidth(strokeWidth); 37 | Roi.setDefaultGroup(group); 38 | return; 39 | } 40 | if (nameChanges) 41 | Roi.saveGroupNames(); 42 | } 43 | 44 | public boolean dialogItemChanged(GenericDialog gd, AWTEvent e) { 45 | int currentGroup = Roi.getDefaultGroup(); 46 | String cname = gd.getNextChoice(); 47 | Color color = Colors.getColor(cname, Color.yellow); 48 | Roi.setColor(color); 49 | if (color.equals(Roi.getColor())) { 50 | Toolbar.repaintTool(Toolbar.POINT); 51 | Toolbar.repaintTool(Toolbar.WAND); 52 | } 53 | Roi.setDefaultStrokeWidth(gd.getNextNumber()); 54 | int group = (int)gd.getNextNumber(); 55 | Vector stringFields = gd.getStringFields(); 56 | TextField nameField = (TextField)(stringFields.get(0)); 57 | if (group>=0 && group<=255 && group!=currentGroup) { 58 | Roi.setDefaultGroup(group); 59 | String name = getGroupName(group); 60 | nameField.setText(name); 61 | } else { 62 | String name = getGroupName(group); 63 | String name2 = nameField.getText(); 64 | if (name2!=null && !name2.equals(name)) { 65 | Roi.setGroupName(group, name2); 66 | nameChanges = true; 67 | } 68 | } 69 | return true; 70 | } 71 | 72 | private String getGroupName(int group) { 73 | String gname = Roi.getGroupName(group); 74 | if (group==0) 75 | gname = "0 = no group"; 76 | else if (gname==null) 77 | gname = "unnamed"; 78 | return gname; 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /ij/gui/RoiListener.java: -------------------------------------------------------------------------------- 1 | package ij.gui; 2 | import ij.ImagePlus; 3 | 4 | /** Plugins that implement this interface are notified when 5 | an ROI is created, modified or deleted. The 6 | Plugins/Utilities/Monitor Events command uses this interface. 7 | */ 8 | public interface RoiListener { 9 | public static final int CREATED = 1; 10 | public static final int MOVED = 2; 11 | public static final int MODIFIED = 3; 12 | public static final int EXTENDED = 4; 13 | public static final int COMPLETED = 5; 14 | public static final int DELETED = 6; 15 | 16 | public void roiModified(ImagePlus imp, int id); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /ij/gui/SaveChangesDialog.java: -------------------------------------------------------------------------------- 1 | package ij.gui; 2 | import ij.IJ; 3 | import java.awt.*; 4 | import java.awt.event.*; 5 | 6 | /** A modal dialog box with a one line message and 7 | "Don't Save", "Cancel" and "Save" buttons. */ 8 | public class SaveChangesDialog extends Dialog implements ActionListener, KeyListener { 9 | private Button dontSave, cancel, save; 10 | private boolean cancelPressed, savePressed; 11 | 12 | public SaveChangesDialog(Frame parent, String fileName) { 13 | super(parent, "Save?", true); 14 | setLayout(new BorderLayout()); 15 | Panel panel = new Panel(); 16 | panel.setLayout(new FlowLayout(FlowLayout.LEFT, 10, 10)); 17 | Component message; 18 | if (fileName.startsWith("Save ")) 19 | message = new Label(fileName); 20 | else { 21 | if (fileName.length()>22) 22 | message = new MultiLineLabel("Save changes to\n" + "\"" + fileName + "\"?"); 23 | else 24 | message = new Label("Save changes to \"" + fileName + "\"?"); 25 | } 26 | message.setFont(new Font("Dialog", Font.BOLD, 12)); 27 | panel.add(message); 28 | add("Center", panel); 29 | 30 | panel = new Panel(); 31 | panel.setLayout(new FlowLayout(FlowLayout.CENTER, 8, 8)); 32 | save = new Button(" Save "); 33 | save.addActionListener(this); 34 | save.addKeyListener(this); 35 | cancel = new Button(" Cancel "); 36 | cancel.addActionListener(this); 37 | cancel.addKeyListener(this); 38 | dontSave = new Button("Don't Save"); 39 | dontSave.addActionListener(this); 40 | dontSave.addKeyListener(this); 41 | if (ij.IJ.isMacintosh()) { 42 | panel.add(dontSave); 43 | panel.add(cancel); 44 | panel.add(save); 45 | } else { 46 | panel.add(save); 47 | panel.add(dontSave); 48 | panel.add(cancel); 49 | } 50 | add("South", panel); 51 | if (ij.IJ.isMacintosh()) 52 | setResizable(false); 53 | pack(); 54 | GUI.centerOnImageJScreen(this); 55 | show(); 56 | } 57 | 58 | public void actionPerformed(ActionEvent e) { 59 | if (e.getSource()==cancel) 60 | cancelPressed = true; 61 | else if (e.getSource()==save) 62 | savePressed = true; 63 | closeDialog(); 64 | } 65 | 66 | /** Returns true if the user dismissed dialog by pressing "Cancel". */ 67 | public boolean cancelPressed() { 68 | if (cancelPressed) 69 | ij.Macro.abort(); 70 | return cancelPressed; 71 | } 72 | 73 | /** Returns true if the user dismissed dialog by pressing "Save". */ 74 | public boolean savePressed() { 75 | return savePressed; 76 | } 77 | 78 | void closeDialog() { 79 | //setVisible(false); 80 | dispose(); 81 | } 82 | 83 | public void keyPressed(KeyEvent e) { 84 | int keyCode = e.getKeyCode(); 85 | IJ.setKeyDown(keyCode); 86 | if (keyCode==KeyEvent.VK_ENTER) 87 | closeDialog(); 88 | else if (keyCode==KeyEvent.VK_ESCAPE) { 89 | cancelPressed = true; 90 | closeDialog(); 91 | IJ.resetEscape(); 92 | } 93 | } 94 | 95 | public void keyReleased(KeyEvent e) {} 96 | public void keyTyped(KeyEvent e) {} 97 | 98 | } 99 | -------------------------------------------------------------------------------- /ij/gui/TrimmedButton.java: -------------------------------------------------------------------------------- 1 | package ij.gui; 2 | import java.awt.*; 3 | import javax.swing.*; 4 | 5 | /** This is an extended Button class used to reduce the width of the HUGE buttons on Mac OS X. */ 6 | public class TrimmedButton extends Button { 7 | private int trim = 0; 8 | 9 | public TrimmedButton(String title, int trim) { 10 | super(title); 11 | if (trim>0) { 12 | LookAndFeel laf = UIManager.getLookAndFeel(); 13 | String name = laf!=null?laf.getName():""; 14 | if (ij.IJ.isMacOSX() && name!=null && !name.equals("Mac OS X")) 15 | trim = 0; 16 | } 17 | this.trim = trim; 18 | } 19 | 20 | public Dimension getMinimumSize() { 21 | return new Dimension(super.getMinimumSize().width-trim, super.getMinimumSize().height); 22 | } 23 | 24 | public Dimension getPreferredSize() { 25 | return getMinimumSize(); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /ij/io/BitBuffer.java: -------------------------------------------------------------------------------- 1 | package ij.io; 2 | 3 | /** 4 | * A class for reading arbitrary numbers of bits from a byte array. 5 | * @author Eric Kjellman egkjellman at wisc.edu 6 | */ 7 | public class BitBuffer { 8 | 9 | private int currentByte; 10 | private int currentBit; 11 | private byte[] byteBuffer; 12 | private int eofByte; 13 | private int[] backMask; 14 | private int[] frontMask; 15 | private boolean eofFlag; 16 | 17 | public BitBuffer(byte[] byteBuffer) { 18 | this.byteBuffer = byteBuffer; 19 | currentByte = 0; 20 | currentBit = 0; 21 | eofByte = byteBuffer.length; 22 | backMask = new int[] {0x0000, 0x0001, 0x0003, 0x0007, 23 | 0x000F, 0x001F, 0x003F, 0x007F}; 24 | frontMask = new int[] {0x0000, 0x0080, 0x00C0, 0x00E0, 25 | 0x00F0, 0x00F8, 0x00FC, 0x00FE}; 26 | } 27 | 28 | public int getBits(int bitsToRead) { 29 | if (bitsToRead == 0) 30 | return 0; 31 | if (eofFlag) 32 | return -1; // Already at end of file 33 | int toStore = 0; 34 | while(bitsToRead != 0 && !eofFlag) { 35 | if (bitsToRead >= 8 - currentBit) { 36 | if (currentBit == 0) { // special 37 | toStore = toStore << 8; 38 | int cb = ((int) byteBuffer[currentByte]); 39 | toStore += (cb<0 ? (int) 256 + cb : (int) cb); 40 | bitsToRead -= 8; 41 | currentByte++; 42 | } else { 43 | toStore = toStore << (8 - currentBit); 44 | toStore += ((int) byteBuffer[currentByte]) & backMask[8 - currentBit]; 45 | bitsToRead -= (8 - currentBit); 46 | currentBit = 0; 47 | currentByte++; 48 | } 49 | } else { 50 | toStore = toStore << bitsToRead; 51 | int cb = ((int) byteBuffer[currentByte]); 52 | cb = (cb<0 ? (int) 256 + cb : (int) cb); 53 | toStore += ((cb) & (0x00FF - frontMask[currentBit])) >> (8 - (currentBit + bitsToRead)); 54 | currentBit += bitsToRead; 55 | bitsToRead = 0; 56 | } 57 | if (currentByte == eofByte) { 58 | eofFlag = true; 59 | return toStore; 60 | } 61 | } 62 | return toStore; 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /ij/io/TextEncoder.java: -------------------------------------------------------------------------------- 1 | package ij.io; 2 | import java.io.*; 3 | import ij.*; 4 | import ij.process.*; 5 | import ij.measure.*; 6 | 7 | /** Saves an image described by an ImageProcessor object as a tab-delimited text file. */ 8 | public class TextEncoder { 9 | 10 | private ImageProcessor ip; 11 | private Calibration cal; 12 | private int precision; 13 | private String delimiter = "\t"; 14 | 15 | /** Constructs a TextEncoder from an ImageProcessor and optional Calibration. */ 16 | public TextEncoder (ImageProcessor ip, Calibration cal, int precision) { 17 | this.ip = ip; 18 | this.cal = cal; 19 | this.precision = precision; 20 | } 21 | 22 | /** Saves the image as a tab-delimited text file. */ 23 | public void write(DataOutputStream out) throws IOException { 24 | PrintWriter pw = new PrintWriter(out); 25 | boolean calibrated = cal!=null && cal.calibrated(); 26 | if (calibrated) 27 | ip.setCalibrationTable(cal.getCTable()); 28 | else 29 | ip.setCalibrationTable(null); 30 | boolean intData = !calibrated && ((ip instanceof ByteProcessor) || (ip instanceof ShortProcessor)); 31 | int width = ip.getWidth(); 32 | int height = ip.getHeight(); 33 | int inc = height/20; 34 | if (inc<1) inc = 1; 35 | //IJ.showStatus("Exporting as text..."); 36 | double value; 37 | for (int y=0; y4) { 24 | if (macro.contains("setForegroundColor")) 25 | IJ.wait(100); 26 | IJ.runMacro(macro); 27 | } 28 | MacroInstaller.autoRun(); 29 | } 30 | 31 | } 32 | 33 | -------------------------------------------------------------------------------- /ij/macro/Symbol.java: -------------------------------------------------------------------------------- 1 | package ij.macro; 2 | 3 | /** Objects of this class are used as entries in the macro language symbol table. */ 4 | public class Symbol implements MacroConstants { 5 | public int type; 6 | public double value; 7 | public String str; 8 | 9 | Symbol(int token, String str) { 10 | type = token&0xffff; 11 | this.str = str; 12 | } 13 | 14 | Symbol(double value) { 15 | this.value = value; 16 | } 17 | 18 | int getFunctionType() { 19 | int t = 0; 20 | if (type>=300 && type<1000) 21 | t = PREDEFINED_FUNCTION; 22 | else if (type>=1000 && type<2000) 23 | t = NUMERIC_FUNCTION; 24 | else if (type>=2000 && type<3000) 25 | t = STRING_FUNCTION; 26 | else if (type>=3000 && type<4000) 27 | t = ARRAY_FUNCTION; 28 | else if (type>=4000 && type<5000) 29 | t = VARIABLE_FUNCTION; 30 | return t; 31 | } 32 | 33 | public String toString() { 34 | return type+" "+value+" "+str; 35 | } 36 | 37 | } // class Symbol 38 | -------------------------------------------------------------------------------- /ij/measure/Measurements.java: -------------------------------------------------------------------------------- 1 | package ij.measure; 2 | 3 | public interface Measurements { 4 | public static final int AREA=1,MEAN=2,STD_DEV=4,MODE=8,MIN_MAX=16, 5 | CENTROID=32,CENTER_OF_MASS=64,PERIMETER=128, LIMIT=256, RECT=512, 6 | LABELS=1024,ELLIPSE=2048,INVERT_Y=4096,CIRCULARITY=8192, 7 | SHAPE_DESCRIPTORS=8192,FERET=16384,INTEGRATED_DENSITY=0x8000, 8 | MEDIAN=0x10000, SKEWNESS=0x20000, KURTOSIS=0x40000, AREA_FRACTION=0x80000, 9 | SLICE=0x100000, STACK_POSITION=0x100000, SCIENTIFIC_NOTATION=0x200000, 10 | ADD_TO_OVERLAY=0x400000, NaN_EMPTY_CELLS=0x800000; 11 | 12 | /** Maximum number of calibration standard (20) */ 13 | public static final int MAX_STANDARDS = 20; 14 | 15 | /** All measurement options */ 16 | public static final int ALL_STATS = AREA+MEAN+STD_DEV+MODE+MIN_MAX+ 17 | CENTROID+CENTER_OF_MASS+PERIMETER+RECT+ 18 | ELLIPSE+SHAPE_DESCRIPTORS+FERET+INTEGRATED_DENSITY+ 19 | MEDIAN+SKEWNESS+KURTOSIS+AREA_FRACTION; 20 | 21 | } 22 | -------------------------------------------------------------------------------- /ij/measure/UserFunction.java: -------------------------------------------------------------------------------- 1 | package ij.measure; 2 | 3 | 4 | /** 5 | * A plugin should implement this interface for minimizing a single-valued function 6 | * or fitting a curve with a custom fit function. 7 | */ 8 | public interface UserFunction { 9 | /** 10 | * A user-supplied function 11 | * @param params When minimizing, array of variables. 12 | * For curve fit array of fit parameters. 13 | * The array contents should not be modified. 14 | * Note that the function can get an array with more 15 | * elements then needed to specify the parameters. 16 | * Ignore the rest (and don't modify them). 17 | * @param x For a fit function, the independent variable of the function. 18 | * Ignore it when using the minimizer. 19 | * @return The result of the function. 20 | */ 21 | public double userFunction(double[] params, double x); 22 | } 23 | 24 | -------------------------------------------------------------------------------- /ij/plugin/AboutBox.java: -------------------------------------------------------------------------------- 1 | package ij.plugin; 2 | import ij.*; 3 | import ij.process.*; 4 | import ij.gui.*; 5 | import java.awt.*; 6 | import ij.io.*; 7 | import java.net.URL; 8 | import java.awt.image.*; 9 | 10 | /** This plugin implements the Help/About ImageJ command by opening 11 | * about.jpg in ij.jar, scaling it 600% and adding text to an overlay. 12 | */ 13 | public class AboutBox implements PlugIn { 14 | private static final int SMALL_FONT=20, LARGE_FONT=45; 15 | private static final Color TEXT_COLOR = new Color(255,255,80); 16 | 17 | public void run(String arg) { 18 | System.gc(); 19 | int lines = 7; 20 | String[] text = new String[lines]; 21 | text[0] = "ImageJ "+ImageJ.VERSION+ImageJ.BUILD; 22 | text[1] = "Wayne Rasband and contributors"; 23 | text[2] = "National Institutes of Health, USA"; 24 | text[3] = "http://imagej.org"; 25 | text[4] = "Java "+System.getProperty("java.version")+(IJ.is64Bit()?" (64-bit)":" (32-bit)"); 26 | text[5] = IJ.freeMemory(); 27 | text[6] = "ImageJ is in the public domain"; 28 | ImageProcessor ip = null; 29 | ImageJ ij = IJ.getInstance(); 30 | if (ij==null) 31 | return; 32 | URL url = ij.getClass().getResource("/about.jpg"); 33 | if (url!=null) { 34 | Image img = null; 35 | try {img = ij.createImage((ImageProducer)url.getContent());} 36 | catch(Exception e) {} 37 | if (img!=null) { 38 | ImagePlus sImp = new ImagePlus("", img); 39 | ip = sImp.getProcessor(); 40 | } 41 | } 42 | if (ip==null) 43 | ip = new ColorProcessor(55,45); 44 | ip = ip.resize(ip.getWidth()*6, ip.getHeight()*6); 45 | ImagePlus imp = new ImagePlus("About ImageJ", ip); 46 | int width = imp.getWidth(); 47 | Overlay overlay = new Overlay(); 48 | Font font = new Font("SansSerif", Font.PLAIN, LARGE_FONT); 49 | int y = 60; 50 | add(text[0], width-20, y, font, TextRoi.RIGHT, overlay); 51 | int xcenter = 410; 52 | font = new Font("SansSerif", Font.PLAIN, SMALL_FONT); 53 | y += 45; 54 | add(text[1], xcenter, y, font, TextRoi.CENTER, overlay); 55 | y += 27; 56 | add(text[2], xcenter, y, font, TextRoi.CENTER, overlay); 57 | y += 27; 58 | add(text[3], xcenter, y, font, TextRoi.CENTER, overlay); 59 | y += 27; 60 | add(text[4], xcenter, y, font, TextRoi.CENTER, overlay); 61 | if (IJ.maxMemory()>0L) { 62 | y += 27; 63 | add(text[5], xcenter, y, font, TextRoi.CENTER, overlay); 64 | } 65 | add(text[6], width-10, ip.getHeight()-10, font, TextRoi.RIGHT, overlay); 66 | imp.setOverlay(overlay); 67 | ImageWindow.centerNextImage(); 68 | imp.show(); 69 | } 70 | 71 | private void add(String text, int x, int y, Font font, int justification, Overlay overlay) { 72 | TextRoi roi = new TextRoi(text, x, y, font); 73 | roi.setStrokeColor(TEXT_COLOR); 74 | roi.setJustification(justification); 75 | overlay.add(roi); 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /ij/plugin/BatchMeasure.java: -------------------------------------------------------------------------------- 1 | package ij.plugin; 2 | import ij.*; 3 | import ij.measure.Measurements; 4 | import ij.plugin.filter.Analyzer; 5 | import java.io.*; 6 | 7 | /** This plugin implements the File/Batch/Measure command, 8 | which measures all the images in a user-specified folder. */ 9 | public class BatchMeasure implements PlugIn { 10 | 11 | public void run(String arg) { 12 | String dir = IJ.getDirectory("Choose a Folder"); 13 | if (dir==null) return; 14 | String[] list = (new File(dir)).list(); 15 | if (list==null) return; 16 | Analyzer.setMeasurement(Measurements.LABELS, true); 17 | for (int i=0; iwidth/2) 25 | radius = width/2; 26 | if (radius>height/2) 27 | radius = height/2; 28 | showDialog(); 29 | if (!macro) 30 | saveRadius = radius; 31 | 32 | } 33 | 34 | private void showDialog() { 35 | Roi roi = imp.getRoi(); 36 | drawRoi(); 37 | GenericDialog gd = new GenericDialog("Circular ROI"); 38 | gd.addSlider("Radius:", 0, imp.getWidth()/2, radius); 39 | gd.addDialogListener(this); 40 | gd.showDialog(); 41 | if (gd.wasCanceled()) { 42 | if (roi==null) 43 | imp.deleteRoi(); 44 | else // restore initial ROI when cancelled 45 | imp.setRoi(roi); 46 | } 47 | } 48 | 49 | public boolean dialogItemChanged(GenericDialog gd, AWTEvent e) { 50 | radius = gd.getNextNumber(); 51 | if (gd.invalidNumber()) 52 | return false; 53 | drawRoi(); 54 | return true; 55 | } 56 | 57 | private void drawRoi() { 58 | double x = xcenter - radius; 59 | double y = ycenter - radius; 60 | Roi roi = new OvalRoi(x, y, radius*2.0, radius*2.0); 61 | imp.setRoi(roi); 62 | showRadius(); 63 | } 64 | 65 | private void showRadius() { 66 | String units = cal.getUnits(); 67 | String s = " radius = "; 68 | if (imp.getProperty("FHT")!=null) { 69 | int width = imp.getWidth(); 70 | if (radius<1.0) 71 | s += "Infinity/c"; 72 | else if (cal.scaled()) 73 | s += IJ.d2s((width/radius)*cal.pixelWidth,2) + " " + units + "/c"; 74 | else 75 | s += IJ.d2s(width/radius,2) + " p/c"; 76 | } else { 77 | int digits = cal.pixelWidth==1.0?0:2; 78 | s += IJ.d2s(radius*cal.pixelWidth,digits)+" "+units; 79 | } 80 | IJ.showStatus(s); 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /ij/plugin/CommandLister.java: -------------------------------------------------------------------------------- 1 | package ij.plugin; 2 | import ij.*; 3 | import ij.text.*; 4 | import ij.util.*; 5 | import java.util.*; 6 | import java.awt.*; 7 | import java.awt.event.*; 8 | 9 | /** This class is used by the Plugins/Shortcuts/List Shortcuts 10 | command to display a list keyboard shortcuts. */ 11 | public class CommandLister implements PlugIn { 12 | 13 | public void run(String arg) { 14 | if (arg.equals("shortcuts")) 15 | listShortcuts(); 16 | else 17 | listCommands(); 18 | } 19 | 20 | public void listCommands() { 21 | Hashtable commands = Menus.getCommands(); 22 | Vector v = new Vector(); 23 | int index = 1; 24 | for (Enumeration en=commands.keys(); en.hasMoreElements();) { 25 | String command = (String)en.nextElement(); 26 | v.addElement(index+"\t"+command+"\t"+(String)commands.get(command)); 27 | index++; 28 | } 29 | String[] list = new String[v.size()]; 30 | v.copyInto((String[])list); 31 | showList("Commands", " \tCommand\tPlugin", list); 32 | } 33 | 34 | public void listShortcuts() { 35 | String[] shortcuts = getShortcuts(); 36 | for (int i=0; i=200+65 && keyCode<=200+90) { 60 | upperCase = true; 61 | keyCode -= 200; 62 | } 63 | String shortcut = KeyEvent.getKeyText(keyCode); 64 | if (!upperCase && shortcut.length()==1) { 65 | char c = shortcut.charAt(0); 66 | if (c>=65 && c<=90) 67 | c += 32; 68 | char[] chars = new char[1]; 69 | chars[0] = c; 70 | shortcut = new String(chars); 71 | } 72 | if (shortcut.length()>1) 73 | shortcut = " " + shortcut; 74 | v.addElement(shortcut+"\t"+(String)shortcuts.get(key)); 75 | } 76 | } 77 | 78 | void showList(String title, String headings, String[] list) { 79 | Arrays.sort(list, String.CASE_INSENSITIVE_ORDER); 80 | ArrayList list2 = new ArrayList(); 81 | for (int i=0; i=ZProjector.METHODS.length) 36 | return null; 37 | int[] dim = imp.getDimensions(); 38 | int projectedStackSize = imp.getStackSize()/groupSize; 39 | imp.setDimensions(1, groupSize, projectedStackSize); 40 | ZProjector zp = new ZProjector(imp); 41 | zp.setMethod(method); 42 | zp.setStartSlice(1); 43 | zp.setStopSlice(groupSize); 44 | zp.doHyperStackProjection(true); 45 | imp.setDimensions(dim[2], dim[3], dim[4]); 46 | 47 | ImagePlus zProjectorOutput = zp.getProjection(); 48 | int[] zProjectDim = zProjectorOutput.getDimensions(); 49 | for (int i=2; isize || (size%groupSize)!=0) { 81 | IJ.error("ZProject", "Group size must divide evenly into the stack size."); 82 | return false; 83 | } 84 | return true; 85 | } 86 | 87 | } -------------------------------------------------------------------------------- /ij/plugin/JavaScriptEvaluator.java: -------------------------------------------------------------------------------- 1 | package ij.plugin; 2 | import ij.*; 3 | import ij.plugin.frame.Editor; 4 | import javax.script.*; 5 | 6 | /** Implements the text editor's Macros/Run command, and the 7 | IJ.runMacroFile() method, when the file name ends with ".js". */ 8 | public class JavaScriptEvaluator implements PlugIn, Runnable { 9 | private Thread thread; 10 | private String script; 11 | private Object result; 12 | private String error; 13 | private boolean evaluating; 14 | ScriptEngine engine; 15 | 16 | // run script in separate thread 17 | public void run(String script) { 18 | if (script.equals("")) 19 | return; 20 | this.script = script; 21 | thread = new Thread(this, "JavaScript"); 22 | thread.setPriority(Math.max(thread.getPriority()-2, Thread.MIN_PRIORITY)); 23 | thread.start(); 24 | } 25 | 26 | // Run script in current thread 27 | public String run(String script, String arg) { 28 | this.script = script; 29 | run(); 30 | return null; 31 | } 32 | 33 | // Evaluates 'script' and returns any error messages as a String. 34 | public String eval(String script) { 35 | this.script = script; 36 | evaluating = true; 37 | run(); 38 | if (error!=null) 39 | return error; 40 | else 41 | return result!=null?""+result:""; 42 | } 43 | 44 | public void run() { 45 | result = null; 46 | error = null; 47 | Thread.currentThread().setContextClassLoader(IJ.getClassLoader()); 48 | if (IJ.isJava19()) 49 | System.setProperty("nashorn.args", "--language=es6"); // Use ECMAScript 6 on Java 9 50 | try { 51 | if (engine==null) { 52 | ScriptEngineManager scriptEngineManager = new ScriptEngineManager(); 53 | engine = scriptEngineManager.getEngineByName("ECMAScript"); 54 | if (engine == null) { 55 | IJ.error("Could not find JavaScript engine"); 56 | return; 57 | } 58 | if (!IJ.isJava18()) { 59 | engine.eval("function load(path) {\n" 60 | + " importClass(Packages.sun.org.mozilla.javascript.internal.Context);\n" 61 | + " importClass(Packages.java.io.FileReader);\n" 62 | + " var cx = Context.getCurrentContext();\n" 63 | + " cx.evaluateReader(this, new FileReader(path), path, 1, null);\n" 64 | + "}"); 65 | } 66 | } 67 | result = engine.eval(script); 68 | } catch(Throwable e) { 69 | String msg = e.getMessage(); 70 | if (msg==null) 71 | msg = ""; 72 | if (msg.startsWith("sun.org.mozilla.javascript.internal.EcmaError: ")) 73 | msg = msg.substring(47, msg.length()); 74 | if (msg.startsWith("sun.org.mozilla.javascript.internal.EvaluatorException")) 75 | msg = "Error"+msg.substring(54, msg.length()); 76 | if (msg.length()>0 && !msg.contains("Macro canceled")) { 77 | if (evaluating) 78 | error = msg; 79 | else 80 | IJ.log(msg); 81 | } 82 | } 83 | } 84 | 85 | public String toString() { 86 | return result!=null?""+result:""; 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /ij/plugin/MeasurementsWriter.java: -------------------------------------------------------------------------------- 1 | package ij.plugin; 2 | import ij.*; 3 | import ij.text.*; 4 | import ij.measure.ResultsTable; 5 | import ij.io.*; 6 | import java.io.*; 7 | import java.awt.Frame; 8 | 9 | /** Saves a table as a csv or tab-delimited text file. */ 10 | public class MeasurementsWriter implements PlugIn { 11 | 12 | public void run(String path) { 13 | save(path); 14 | } 15 | 16 | public boolean save(String path) { 17 | Frame frame = WindowManager.getFrontWindow(); 18 | if (frame!=null && (frame instanceof TextWindow) && !"Log".equals(frame.getTitle())) { 19 | TextWindow tw = (TextWindow)frame; 20 | return tw.getTextPanel().saveAs(path); 21 | } else if (IJ.isResultsWindow()) { 22 | TextPanel tp = IJ.getTextPanel(); 23 | if (tp!=null) { 24 | if (!tp.saveAs(path)) 25 | return false; 26 | } 27 | } else { 28 | ResultsTable rt = ResultsTable.getResultsTable(); 29 | if (rt==null || rt.size()==0) { 30 | frame = WindowManager.getFrame("Results"); 31 | if (frame==null || !(frame instanceof TextWindow)) 32 | return false; 33 | else { 34 | TextWindow tw = (TextWindow)frame; 35 | return tw.getTextPanel().saveAs(path); 36 | } 37 | } 38 | if (path.equals("")) { 39 | SaveDialog sd = new SaveDialog("Save as Text", "Results", Prefs.defaultResultsExtension()); 40 | String file = sd.getFileName(); 41 | if (file == null) return false; 42 | path = sd.getDirectory() + file; 43 | } 44 | return rt.save(path); 45 | } 46 | return true; 47 | } 48 | 49 | } 50 | 51 | -------------------------------------------------------------------------------- /ij/plugin/PlugIn.java: -------------------------------------------------------------------------------- 1 | package ij.plugin; 2 | 3 | /** Plugins that acquire images or display windows should 4 | implement this interface. Plugins that process images 5 | should implement the PlugInFilter interface. */ 6 | public interface PlugIn { 7 | 8 | /** This method is called when the plugin is loaded. 9 | 'arg', which may be blank, is the argument specified 10 | for this plugin in IJ_Props.txt. */ 11 | public void run(String arg); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /ij/plugin/PlugInInterpreter.java: -------------------------------------------------------------------------------- 1 | package ij.plugin; 2 | 3 | /** Plugins that run scripts (e.g., BeanShell, Jython) extend this class. */ 4 | public abstract class PlugInInterpreter implements PlugIn { 5 | 6 | /** Run script on separate thread. */ 7 | public void run(String script) { 8 | } 9 | 10 | /** Run script on current thread. */ 11 | public abstract String run(String script, String arg); 12 | 13 | /** Returns the value returned by the script, if any, or null. */ 14 | public abstract String getReturnValue(); 15 | 16 | /** Returns the name of this PlugInInterpreter. */ 17 | public abstract String getName(); 18 | 19 | /** Returns the import statements that are added to the script. */ 20 | public abstract String getImports(); 21 | 22 | /** Returns the version of ImageJ at the time this plugin was created. */ 23 | public abstract String getVersion(); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /ij/plugin/RandomOvals.txt: -------------------------------------------------------------------------------- 1 | 2 | newImage("Untitled", "RGB", 400, 400, 1); 3 | width = getWidth(); 4 | height = getHeight(); 5 | for (i=0; i<1000; i++) { 6 | if (nSlices!=1) exit; 7 | w = random()*width/2+1; 8 | h = random()*width/2+1; 9 | x = random()*width-w/2; 10 | y = random()*height-h/2; 11 | setForegroundColor(random()*255, random()*255, random()*255); 12 | makeOval(x, y, w, h); 13 | run("Fill"); 14 | } 15 | 16 | -------------------------------------------------------------------------------- /ij/plugin/Raw.java: -------------------------------------------------------------------------------- 1 | package ij.plugin; 2 | 3 | import java.awt.*; 4 | import java.io.*; 5 | import ij.*; 6 | import ij.io.*; 7 | 8 | /** This plugin implements the File/Import/Raw command. */ 9 | public class Raw implements PlugIn { 10 | 11 | private static String defaultDirectory = null; 12 | 13 | public void run(String arg) { 14 | OpenDialog od = new OpenDialog("Open Raw...", arg); 15 | String directory = od.getDirectory(); 16 | String fileName = od.getFileName(); 17 | if (fileName==null) 18 | return; 19 | ImportDialog d = new ImportDialog(fileName, directory); 20 | d.openImage(); 21 | } 22 | 23 | /** Opens the image at 'filePath' using the format specified by 'fi'. */ 24 | public static ImagePlus open(String filePath, FileInfo fi) { 25 | File f = new File(filePath); 26 | String parent = f.getParent(); 27 | if (parent!=null) 28 | fi.directory = parent+ "/"; 29 | fi.fileName = f.getName(); 30 | return (new FileOpener(fi)).open(false); 31 | } 32 | 33 | 34 | /** Opens all the images in the specified directory as a stack, 35 | using the format specified by 'fi'. */ 36 | public static ImagePlus openAll(String directory, FileInfo fi) { 37 | ImagePlus imp = openAllVirtual(directory,fi); 38 | if (imp!=null) 39 | return imp.duplicate(); 40 | else 41 | return null; 42 | } 43 | 44 | /** Opens all the images in the specified directory as a virtual stack, 45 | using the format specified by 'fi'. */ 46 | public static ImagePlus openAllVirtual(String directory, FileInfo fi) { 47 | String[] list = new File(directory).list(); 48 | if (list==null) 49 | return null; 50 | FolderOpener fo = new FolderOpener(); 51 | list = fo.trimFileList(list); 52 | list = fo.sortFileList(list); 53 | if (list==null) 54 | return null; 55 | directory = IJ.addSeparator(directory); 56 | FileInfo[] info = new FileInfo[list.length]; 57 | for (int i=0; i60) delay=60; 35 | for (int i=0; i4 && i==delay-2) IJ.beep(); 39 | } 40 | return captureScreen(); 41 | } 42 | 43 | 44 | /** Captures the entire screen and returns it as an ImagePlus. */ 45 | public ImagePlus captureScreen() { 46 | ImagePlus imp = null; 47 | try { 48 | Robot robot = new Robot(); 49 | Rectangle r = GUI.getScreenBounds(IJ.getInstance()); // screen showing "ImageJ" window 50 | Image img = robot.createScreenCapture(r); 51 | if (img!=null) imp = new ImagePlus("Screenshot", img); 52 | } catch(Exception e) {} 53 | return imp; 54 | } 55 | 56 | /** Captures the active image window and returns it as an ImagePlus. */ 57 | public ImagePlus captureImage() { 58 | ImagePlus imp = IJ.getImage(); 59 | if (imp==null) { 60 | IJ.noImage(); 61 | return null; 62 | } 63 | ImageWindow win = imp.getWindow(); 64 | if (win==null) return null; 65 | win.toFront(); 66 | IJ.wait(500); 67 | Point loc = win.getLocation(); 68 | ImageCanvas ic = win.getCanvas(); 69 | Rectangle bounds = ic.getBounds(); 70 | loc.x += bounds.x; 71 | loc.y += bounds.y; 72 | Rectangle r = new Rectangle(loc.x, loc.y, bounds.width, bounds.height); 73 | ImagePlus imp2 = null; 74 | Image img = null; 75 | boolean wasHidden = ic.hideZoomIndicator(true); 76 | IJ.wait(250); 77 | try { 78 | Robot robot = new Robot(); 79 | img = robot.createScreenCapture(r); 80 | } catch(Exception e) { } 81 | ic.hideZoomIndicator(wasHidden); 82 | if (img!=null) { 83 | String title = WindowManager.getUniqueName(imp.getTitle()); 84 | imp2 = new ImagePlus(title, img); 85 | } 86 | return imp2; 87 | } 88 | 89 | } 90 | 91 | -------------------------------------------------------------------------------- /ij/plugin/StackInserter.java: -------------------------------------------------------------------------------- 1 | package ij.plugin; 2 | import java.awt.*; 3 | import java.io.*; 4 | import ij.*; 5 | import ij.gui.*; 6 | import ij.process.*; 7 | 8 | /** This plugin, which implements the Image/Stacks/Tools/Insert 9 | command, inserts an image or stack into another image or stack. */ 10 | public class StackInserter implements PlugIn { 11 | 12 | private static int index1; 13 | private static int index2; 14 | private static int x, y; 15 | 16 | public void run(String arg) { 17 | int[] wList = WindowManager.getIDList(); 18 | if (wList==null) { 19 | IJ.showMessage("Stack Inserter", "No windows are open."); 20 | return; 21 | } 22 | if (wList.length==1) { 23 | IJ.showMessage("Stack Inserter", "At least two windows must be open."); 24 | return; 25 | } 26 | String[] titles = new String[wList.length]; 27 | for (int i=0; i=titles.length)index1 = 0; 35 | if (index2>=titles.length)index2 = 0; 36 | GenericDialog gd = new GenericDialog("Stack Inserter"); 37 | gd.addChoice("Source: ", titles, titles[index1]); 38 | gd.addChoice("Destination: ", titles, titles[index2]); 39 | gd.addNumericField("X Location: ", 0, 0); 40 | gd.addNumericField("Y Location: ", 0, 0); 41 | gd.showDialog(); 42 | if (gd.wasCanceled()) 43 | return; 44 | index1 = gd.getNextChoiceIndex(); 45 | index2 = gd.getNextChoiceIndex(); 46 | x = (int)gd.getNextNumber(); 47 | y = (int)gd.getNextNumber(); 48 | String title1 = titles[index1]; 49 | String title2 = titles[index2]; 50 | ImagePlus imp1 = WindowManager.getImage(wList[index1]); 51 | ImagePlus imp2 = WindowManager.getImage(wList[index2]); 52 | if (imp1.getType()!= imp2.getType()) { 53 | IJ.showMessage("Stack Inserter", "The source and destination must be the same type."); 54 | return; 55 | } 56 | if (imp1== imp2) { 57 | IJ.showMessage("Stack Inserter", "The source and destination must be different."); 58 | return; 59 | } 60 | insert(imp1, imp2, x, y); 61 | } 62 | 63 | public void insert(ImagePlus imp1, ImagePlus imp2, int x, int y) { 64 | ImageStack stack1 = imp1.getStack(); 65 | ImageStack stack2 = imp2.getStack(); 66 | int size1 = stack1.getSize(); 67 | int size2 = stack2.getSize(); 68 | ImageProcessor ip1, ip2; 69 | for (int i=1; i<=size2; i++) { 70 | ip1 = stack1.getProcessor(i<=size1?i:size1); 71 | ip2 = stack2.getProcessor(i); 72 | ip2.insert(ip1, x, y); 73 | stack2.setPixels(ip2.getPixels(), i); 74 | } 75 | imp2.setStack(null, stack2); 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /ij/plugin/StackMaker.java: -------------------------------------------------------------------------------- 1 | package ij.plugin; 2 | import ij.*; 3 | import ij.gui.*; 4 | import ij.process.*; 5 | import ij.plugin.*; 6 | import ij.util.Tools; 7 | 8 | /** The plugin implements the Image/Stacks/Tools/Montage to Stack command. 9 | It creates a w*h image stack from an wxh image montage. 10 | This is the opposite of what the "Make Montage" command does. 11 | 2010.04.20,TF: Final stack can be cropped to remove border around frames. 12 | */ 13 | public class StackMaker implements PlugIn { 14 | private int rows; 15 | private int columns; 16 | private int border; 17 | 18 | public void run(String arg) { 19 | ImagePlus imp = WindowManager.getCurrentImage(); 20 | if (imp==null) { 21 | IJ.noImage(); 22 | return; 23 | } 24 | if (imp.getStackSize()>1) { 25 | IJ.error("This command requires a montage"); 26 | return; 27 | } 28 | String options = Macro.getOptions(); 29 | if (options!=null) { 30 | options = options.replace("images_per_row=", "columns="); 31 | options = options.replace("images_per_column=", "rows="); 32 | } 33 | columns = info("xMontage", imp, 2); 34 | rows = info("yMontage", imp, 2); 35 | String montageHeight = (String)imp.getProperty("yMontage"); 36 | if (montageHeight!=null) 37 | rows = Integer.parseInt(montageHeight); 38 | GenericDialog gd = new GenericDialog("Stack Maker"); 39 | gd.addNumericField("Columns: ", columns, 0); 40 | gd.addNumericField("Rows: ", rows, 0); 41 | gd.addNumericField("Border width: ", border, 0); 42 | gd.showDialog(); 43 | if (gd.wasCanceled()) 44 | return; 45 | columns = (int)gd.getNextNumber(); 46 | rows = (int)gd.getNextNumber(); 47 | border = (int)gd.getNextNumber(); 48 | if (rows==0 || columns==0) 49 | return; 50 | ImageStack stack = makeStack(imp.getProcessor(), rows, columns, border); 51 | new ImagePlus("Stack", stack).show(); 52 | } 53 | 54 | private int info(String key, ImagePlus imp, int value) { 55 | String svalue = imp.getStringProperty(key); 56 | if (svalue!=null) 57 | value = Integer.parseInt(svalue); 58 | return value; 59 | } 60 | 61 | public ImageStack makeStack(ImageProcessor ip, int rows, int columns, int border) { 62 | int stackSize = rows*columns; 63 | int width = ip.getWidth()/columns; 64 | int height = ip.getHeight()/rows; 65 | //IJ.log("makeStack: "+rows+" "+columns+" "+border+" "+width+" "+height); 66 | ImageStack stack = new ImageStack(width, height); 67 | for (int y=0; y0) { 73 | int cropwidth = width-border-border/2; 74 | int cropheight = height-border-border/2; 75 | StackProcessor sp = new StackProcessor(stack,ip); 76 | stack = sp.crop(border, border, cropwidth, cropheight); 77 | } 78 | return stack; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /ij/plugin/StackReverser.java: -------------------------------------------------------------------------------- 1 | package ij.plugin; 2 | import ij.*; 3 | import ij.process.*; 4 | import ij.measure.Calibration; 5 | 6 | /** This plugin implements the Image/Transform/Flip Z and 7 | Image/Stacks/Tools/Reverse commands. */ 8 | public class StackReverser implements PlugIn { 9 | 10 | public void run(String arg) { 11 | ImagePlus imp = IJ.getImage(); 12 | if (imp.getStackSize()==1) { 13 | IJ.error("Flip Z", "This command requires a stack"); 14 | return; 15 | } 16 | if (imp.isHyperStack()) { 17 | IJ.error("Flip Z", "This command does not currently work with hyperstacks."); 18 | return; 19 | } 20 | flipStack(imp); 21 | } 22 | 23 | public void flipStack(ImagePlus imp) { 24 | ImageStack stack = imp.getStack(); 25 | int n = stack.size(); 26 | if (n==1) 27 | return; 28 | Calibration cal = imp.getCalibration(); 29 | double min = cal.getCValue(imp.getDisplayRangeMin()); 30 | double max = cal.getCValue(imp.getDisplayRangeMax()); 31 | ImageStack stack2 = new ImageStack(imp.getWidth(), imp.getHeight(), n); 32 | for (int i=1; i<=n; i++) { 33 | stack2.setPixels(stack.getPixels(i), n-i+1); 34 | stack2.setSliceLabel(stack.getSliceLabel(i), n-i+1); 35 | } 36 | stack2.setColorModel(stack.getColorModel()); 37 | imp.setStack(stack2); 38 | if (imp.isComposite()) { 39 | ((CompositeImage)imp).reset(); 40 | imp.updateAndDraw(); 41 | } 42 | IJ.setMinAndMax(imp, min, max); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /ij/plugin/Stack_Statistics.java: -------------------------------------------------------------------------------- 1 | package ij.plugin; 2 | import ij.*; 3 | import ij.process.*; 4 | import ij.plugin.filter.Analyzer; 5 | import ij.measure.*; 6 | import ij.gui.Roi; 7 | import java.awt.Rectangle; 8 | 9 | /** This plugin implements the Image/Stacks/Statistics command. */ 10 | public class Stack_Statistics implements PlugIn { 11 | 12 | public void run(String arg) { 13 | ImagePlus imp = IJ.getImage(); 14 | int measurements = Analyzer.getMeasurements(); 15 | Analyzer.setMeasurements(measurements | Measurements.LIMIT); 16 | ImageStatistics stats = new StackStatistics(imp); 17 | Analyzer.setMeasurements(measurements); 18 | ResultsTable rt = Analyzer.getResultsTable(); 19 | rt.incrementCounter(); 20 | Roi roi = imp.getRoi(); 21 | if (roi!=null && !roi.isArea()) { 22 | imp.deleteRoi(); 23 | roi = null; 24 | } 25 | double stackVoxels = 0.0; 26 | double images = imp.getStackSize(); 27 | if (roi==null) 28 | stackVoxels = imp.getWidth()*imp.getHeight()*images; 29 | else if (roi.getType()==Roi.RECTANGLE) { 30 | Rectangle r = roi.getBounds(); 31 | stackVoxels = r.width*r.height*images; 32 | } else { 33 | Analyzer.setMeasurements(measurements & ~Measurements.LIMIT); 34 | ImageStatistics stats2 = new StackStatistics(imp); 35 | Analyzer.setMeasurements(measurements); 36 | stackVoxels = stats2.longPixelCount; 37 | } 38 | Calibration cal = imp.getCalibration(); 39 | String units = cal.getUnits(); 40 | double scale = cal.pixelWidth*cal.pixelHeight*cal.pixelDepth; 41 | rt.addValue("Voxels", stats.longPixelCount); 42 | if (scale!=1.0) 43 | rt.addValue("Volume("+units+"^3)", stats.longPixelCount*scale); 44 | rt.addValue("%Volume", stats.longPixelCount*100.0/stackVoxels); 45 | rt.addValue("Mean", stats.mean); 46 | rt.addValue("StdDev", stats.stdDev); 47 | rt.addValue("Min", stats.min); 48 | rt.addValue("Max", stats.max); 49 | rt.addValue("Mode", stats.dmode); 50 | rt.addValue("Median", stats.median); 51 | rt.show("Results"); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /ij/plugin/TextFileReader.java: -------------------------------------------------------------------------------- 1 | package ij.plugin; 2 | 3 | //import java.awt.*; 4 | //import java.awt.image.*; 5 | //import java.io.*; 6 | import ij.*; 7 | //import ij.io.*; 8 | //import ij.process.*; 9 | 10 | 11 | /** This plugin displays the contents of a text file in a window. */ 12 | public class TextFileReader implements PlugIn { 13 | 14 | public void run(String arg) { 15 | new ij.text.TextWindow(arg,400,450); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /ij/plugin/TextWriter.java: -------------------------------------------------------------------------------- 1 | package ij.plugin; 2 | import ij.*; 3 | import ij.process.*; 4 | import ij.io.*; 5 | import ij.text.*; 6 | import ij.plugin.frame.Editor; 7 | import java.awt.*; 8 | 9 | /** This plugin implements the File/Save As/Text command, which saves the 10 | contents of Editor windows and TextWindows (e.g., "Log" and "Results"). */ 11 | public class TextWriter implements PlugIn { 12 | 13 | public void run(String arg) { 14 | saveText(); 15 | } 16 | 17 | void saveText() { 18 | Frame frame = WindowManager.getFrontWindow(); 19 | if (frame!=null && (frame instanceof TextWindow)) { 20 | TextPanel tp = ((TextWindow)frame).getTextPanel(); 21 | tp.saveAs(""); 22 | } else if (frame!=null && (frame instanceof Editor)) { 23 | Editor ed = (Editor)frame; 24 | ed.saveAs(); 25 | } else { 26 | IJ.error("Save As Text", 27 | "This command requires a TextWindow, such\n" 28 | + "as the \"Log\" window, or an Editor window. Use\n" 29 | + "File>Save>Text Image to save an image as text."); 30 | } 31 | } 32 | 33 | } 34 | 35 | -------------------------------------------------------------------------------- /ij/plugin/WandToolOptions.java: -------------------------------------------------------------------------------- 1 | package ij.plugin; 2 | import ij.*; 3 | import ij.gui.*; 4 | import ij.process.*; 5 | import ij.io.*; 6 | import ij.plugin.filter.*; 7 | import java.awt.*; 8 | import java.awt.event.*; 9 | import java.util.Vector; 10 | 11 | /** This plugin implements the Edit/Options/Wand Tool command. */ 12 | public class WandToolOptions implements PlugIn, DialogListener { 13 | private static final String[] modes = {"Legacy", "4-connected", "8-connected"}; 14 | private static String mode = modes[0]; 15 | private static double tolerance; 16 | private ImagePlus imp; 17 | private boolean showCheckbox; 18 | private static int startx, starty; 19 | private static int ID; 20 | 21 | public void run(String arg) { 22 | imp = WindowManager.getCurrentImage(); 23 | Roi roi = imp!=null?imp.getRoi():null; 24 | boolean selection = roi!=null && (roi.getType()==Roi.TRACED_ROI||roi.getType()==Roi.POLYGON); 25 | if (imp==null || (ID!=0&&imp.getID()!=ID) || !selection) 26 | startx = starty = 0; 27 | ID = imp!=null?imp.getID():0; 28 | double sliderMax = 255; 29 | int depth = imp!=null?imp.getBitDepth():0; 30 | if (depth==16 || depth==32) { 31 | sliderMax = imp.getProcessor().getMax(); 32 | if (depth==32) sliderMax+=0.0000000001; 33 | } 34 | showCheckbox = imp!=null && depth!=24 && WindowManager.getFrame("Threshold")==null && !imp.isThreshold(); 35 | GenericDialog gd = new GenericDialog("Wand Tool"); 36 | gd.addSlider("Tolerance: ", 0, sliderMax, tolerance); 37 | gd.addChoice("Mode:", modes, mode); 38 | if (showCheckbox) 39 | gd.addCheckbox("Enable Thresholding", false); 40 | gd.addCheckbox("Smooth if thresholded", Prefs.smoothWand); 41 | if (showCheckbox) { 42 | gd.setInsets(2,0,0); 43 | gd.addMessage("Thresholded objects are traced and \"Tolerance\"\nis ignored when thresholding is enabled."); 44 | } 45 | gd.addDialogListener(this); 46 | gd.showDialog(); 47 | } 48 | 49 | public boolean dialogItemChanged(GenericDialog gd, AWTEvent e) { 50 | if (gd.wasCanceled()) 51 | return false; 52 | tolerance = gd.getNextNumber(); 53 | mode = gd.getNextChoice(); 54 | if (showCheckbox) { 55 | if (gd.getNextBoolean()) { 56 | imp.deleteRoi(); 57 | IJ.run("Threshold..."); 58 | } 59 | } 60 | Prefs.smoothWand = gd.getNextBoolean(); 61 | if (startx>0||starty>0) 62 | IJ.doWand(startx, starty, tolerance, mode+(Prefs.smoothWand?" smooth":"")); 63 | return true; 64 | } 65 | 66 | public static String getMode() { 67 | return mode; 68 | } 69 | 70 | public static double getTolerance() { 71 | return tolerance; 72 | } 73 | 74 | public static final void setStart(int x, int y) { 75 | startx = x; 76 | starty = y; 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /ij/plugin/XY_Reader.java: -------------------------------------------------------------------------------- 1 | package ij.plugin; 2 | import ij.*; 3 | import ij.process.*; 4 | import ij.gui.*; 5 | import java.awt.*; 6 | import ij.measure.*; 7 | import ij.plugin.TextReader; 8 | 9 | /** This plugin implements the File/Import/XY Coordinates command. It reads a 10 | two column text file, such as those created by File/Save As/XY Coordinates, 11 | as a polygon ROI. The ROI is displayed in the current image or, if the image 12 | is too small, in a new blank image. 13 | */ 14 | public class XY_Reader implements PlugIn { 15 | 16 | public void run(String arg) { 17 | TextReader tr = new TextReader(); 18 | ImageProcessor ip = tr.open(); 19 | if (ip==null) 20 | return; 21 | int width = ip.getWidth(); 22 | int height = ip.getHeight(); 23 | if (width!=2 || height<3) { 24 | IJ.showMessage("XY Reader", "Two column text file required"); 25 | return; 26 | } 27 | float[] x = new float[height]; 28 | float[] y = new float[height]; 29 | boolean allIntegers = true; 30 | double length = 0.0; 31 | for (int i=0; i0) { 37 | double dx = x[i] - x[i-1]; 38 | double dy = y[i] - y[i-1]; 39 | length += Math.sqrt(dx*dx+dy*dy); 40 | } 41 | } 42 | Roi roi = null; 43 | int type = length/x.length>10?Roi.POLYGON:Roi.FREEROI; 44 | if (allIntegers) 45 | roi = new PolygonRoi(Roi.toIntR(x), Roi.toIntR(y), height, type); 46 | else 47 | roi = new PolygonRoi(x, y, height, type); 48 | Rectangle r = roi.getBoundingRect(); 49 | ImagePlus imp = WindowManager.getCurrentImage(); 50 | if (imp==null || imp.getWidth()1 && slice==imp.getStackSize()) 39 | imp.resetDisplayRange(); 40 | return; 41 | } 42 | 43 | if (arg.equals("smooth")) { 44 | ip.setSnapshotCopyMode(true); 45 | ip.smooth(); 46 | ip.setSnapshotCopyMode(false); 47 | return; 48 | } 49 | 50 | if (arg.equals("sharpen")) { 51 | ip.setSnapshotCopyMode(true); 52 | ip.sharpen(); 53 | ip.setSnapshotCopyMode(false); 54 | return; 55 | } 56 | 57 | if (arg.equals("edge")) { 58 | ip.setSnapshotCopyMode(true); 59 | ip.findEdges(); 60 | ip.setSnapshotCopyMode(false); 61 | return; 62 | } 63 | 64 | if (arg.equals("add")) { 65 | ip.noise(25.0); 66 | return; 67 | } 68 | 69 | if (arg.equals("noise")) { 70 | if (canceled) 71 | return; 72 | slice++; 73 | if (slice==1) { 74 | GenericDialog gd = new GenericDialog("Gaussian Noise"); 75 | gd.addNumericField("Standard Deviation:", sd, 2); 76 | gd.showDialog(); 77 | if (gd.wasCanceled()) { 78 | canceled = true; 79 | return; 80 | } 81 | sd = gd.getNextNumber(); 82 | } 83 | ip.noise(sd); 84 | IJ.register(Filters.class); 85 | return; 86 | } 87 | 88 | } 89 | 90 | /** Returns the default standard deviation used by Process/Noise/Add Specified Noise. */ 91 | public static double getSD() { 92 | return sd; 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /ij/plugin/filter/Info.java: -------------------------------------------------------------------------------- 1 | package ij.plugin.filter; 2 | import ij.ImagePlus; 3 | import ij.process.ImageProcessor; 4 | import ij.plugin.ImageInfo; 5 | 6 | /** 7 | * @deprecated 8 | * replaced by ij.plugin.ImageInfo 9 | */ 10 | public class Info implements PlugInFilter { 11 | private ImagePlus imp; 12 | 13 | public int setup(String arg, ImagePlus imp) { 14 | this.imp = imp; 15 | return DOES_ALL+NO_CHANGES; 16 | } 17 | 18 | public void run(ImageProcessor ip) { 19 | } 20 | 21 | public String getImageInfo(ImagePlus imp, ImageProcessor ip) { 22 | ImageInfo info = new ImageInfo(); 23 | return info.getImageInfo(imp); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /ij/plugin/filter/RGBStackSplitter.java: -------------------------------------------------------------------------------- 1 | package ij.plugin.filter; 2 | import ij.*; 3 | import ij.process.*; 4 | import ij.plugin.ChannelSplitter; 5 | 6 | /** Deprecated; replaced by ij.plugin.ChannelSplitter. */ 7 | public class RGBStackSplitter implements PlugInFilter { 8 | ImagePlus imp; 9 | public ImageStack red, green, blue; 10 | 11 | public int setup(String arg, ImagePlus imp) { 12 | this.imp = imp; 13 | (new ChannelSplitter()).run(arg); 14 | return DONE; 15 | } 16 | 17 | public void run(ImageProcessor ip) { 18 | } 19 | 20 | /** Deprecated; replaced by ij.plugin.ChannelSplitter. */ 21 | public void split(ImagePlus imp) { 22 | WindowManager.setTempCurrentImage(imp); 23 | (new ChannelSplitter()).run(""); 24 | } 25 | 26 | /** Deprecated; replaced by ChannelSplitter.splitRGB(). */ 27 | public void split(ImageStack rgb, boolean keepSource) { 28 | ImageStack[] channels = ChannelSplitter.splitRGB(rgb, keepSource); 29 | red = channels[0]; 30 | green = channels[1]; 31 | blue = channels[2]; 32 | } 33 | 34 | } 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /ij/plugin/filter/RoiWriter.java: -------------------------------------------------------------------------------- 1 | package ij.plugin.filter; 2 | 3 | import java.awt.*; 4 | import java.awt.image.*; 5 | import java.io.*; 6 | import ij.*; 7 | import ij.process.*; 8 | import ij.io.*; 9 | import ij.gui.*; 10 | 11 | /** Saves the current ROI outline to a file. RoiDecoder.java 12 | has a description of the file format. 13 | @see ij.io.RoiDecoder 14 | @see ij.plugin.RoiReader 15 | */ 16 | public class RoiWriter implements PlugInFilter { 17 | ImagePlus imp; 18 | 19 | public int setup(String arg, ImagePlus imp) { 20 | this.imp = imp; 21 | return DOES_ALL+ROI_REQUIRED+NO_CHANGES; 22 | } 23 | 24 | public void run(ImageProcessor ip) { 25 | try { 26 | saveRoi(imp); 27 | } catch (IOException e) { 28 | String msg = e.getMessage(); 29 | if (msg==null || msg.equals("")) 30 | msg = ""+e; 31 | IJ.error("ROI Writer", msg); 32 | } 33 | } 34 | 35 | public void saveRoi(ImagePlus imp) throws IOException{ 36 | Roi roi = imp.getRoi(); 37 | if (roi==null) 38 | throw new IllegalArgumentException("ROI required"); 39 | String name = roi.getName(); 40 | if (name==null) 41 | name = imp.getTitle(); 42 | SaveDialog sd = new SaveDialog("Save Selection...", name, ".roi"); 43 | name = sd.getFileName(); 44 | if (name == null) 45 | return; 46 | String dir = sd.getDirectory(); 47 | RoiEncoder re = new RoiEncoder(dir+name); 48 | re.write(roi); 49 | if (name.endsWith(".roi")) 50 | name = name.substring(0, name.length()-4); 51 | roi.setName(name); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /ij/plugin/filter/SaltAndPepper.java: -------------------------------------------------------------------------------- 1 | package ij.plugin.filter; 2 | import java.awt.*; 3 | import java.util.*; 4 | import ij.*; 5 | import ij.process.*; 6 | 7 | /** Implements ImageJ's Process/Noise/Salt and Pepper command. */ 8 | public class SaltAndPepper implements PlugInFilter { 9 | 10 | Random r = new Random(); 11 | 12 | public int setup(String arg, ImagePlus imp) { 13 | return IJ.setupDialog(imp, DOES_8G+DOES_8C+SUPPORTS_MASKING); 14 | } 15 | 16 | public void run(ImageProcessor ip) { 17 | add(ip, 0.05); 18 | } 19 | 20 | public int rand(int min, int max) { 21 | return min + r.nextInt(max-min); 22 | } 23 | 24 | public void add(ImageProcessor ip, double percent) { 25 | Rectangle roi = ip.getRoi(); 26 | int n = (int)(percent*roi.width*roi.height); 27 | byte[] pixels = (byte[])ip.getPixels(); 28 | int rx, ry; 29 | int width = ip.getWidth(); 30 | int xmin = roi.x; 31 | int xmax = roi.x+roi.width; 32 | int ymin = roi.y; 33 | int ymax = roi.y+roi.height; 34 | for (int i=0; i=0||roi.contains(ox,oy)))) { 21 | arrow = new Arrow(sx, sy, imp); 22 | if (imp.okToDeleteRoi()) 23 | imp.setRoi(arrow, false); 24 | e.consume(); 25 | } 26 | } 27 | 28 | public void mouseDragged(ImagePlus imp, MouseEvent e) { 29 | ImageCanvas ic = imp.getCanvas(); 30 | int sx = e.getX(); 31 | int sy = e.getY(); 32 | int ox = ic.offScreenX(sx); 33 | int oy = ic.offScreenY(sy); 34 | Roi roi = imp.getRoi(); 35 | if (roi!=null && (roi instanceof Arrow) && roi.contains(ox,oy)) 36 | roi.mouseDragged(e); 37 | else if (arrow!=null) 38 | arrow.mouseDragged(e); 39 | e.consume(); 40 | } 41 | 42 | public void mouseReleased(ImagePlus imp, MouseEvent e) { 43 | ImageCanvas ic = imp.getCanvas(); 44 | int sx = e.getX(); 45 | int sy = e.getY(); 46 | int ox = ic.offScreenX(sx); 47 | int oy = ic.offScreenY(sy); 48 | Roi roi = imp.getRoi(); 49 | if (arrow!=null && !(roi!=null && (roi instanceof Arrow) && roi.contains(ox,oy))) { 50 | arrow.mouseReleased(e); 51 | e.consume(); 52 | } 53 | } 54 | 55 | public void showOptionsDialog() { 56 | IJ.doCommand("Arrow Tool..."); 57 | } 58 | 59 | public String getToolIcon() { 60 | return "C037L0ff0L74f0Lb8f0L74b8"; 61 | } 62 | 63 | public String getToolName() { 64 | return "Arrow Tool"; 65 | } 66 | 67 | } 68 | 69 | 70 | -------------------------------------------------------------------------------- /ij/plugin/tool/MacroToolRunner.java: -------------------------------------------------------------------------------- 1 | package ij.plugin.tool; 2 | import ij.macro.Program; 3 | import ij.plugin.MacroInstaller; 4 | 5 | public class MacroToolRunner extends PlugInTool { 6 | MacroInstaller installer; 7 | 8 | public MacroToolRunner(MacroInstaller installer) { 9 | this.installer = installer; 10 | } 11 | 12 | public void runMacroTool(String name) { 13 | if (installer!=null) 14 | installer.runMacroTool(name); 15 | } 16 | 17 | public void runMenuTool(String name, String command) { 18 | if (installer!=null) 19 | installer.runMenuTool(name, command); 20 | } 21 | 22 | public Program getMacroProgram() { 23 | if (installer!=null) 24 | return installer.getProgram(); 25 | else 26 | return null; 27 | } 28 | 29 | public int getMacroCount() { 30 | if (installer!=null) 31 | return installer.getMacroCount(); 32 | else 33 | return 0; 34 | } 35 | 36 | } 37 | 38 | 39 | -------------------------------------------------------------------------------- /ij/plugin/tool/PlugInTool.java: -------------------------------------------------------------------------------- 1 | package ij.plugin.tool; 2 | import ij.ImagePlus; 3 | import ij.plugin.PlugIn; 4 | import ij.macro.Program; 5 | import ij.gui.Toolbar; 6 | import java.awt.event.*; 7 | 8 | public abstract class PlugInTool implements PlugIn { 9 | 10 | public void run(String arg) { 11 | Toolbar.addPlugInTool(this); 12 | } 13 | 14 | public void mousePressed(ImagePlus imp, MouseEvent e) {e.consume();} 15 | 16 | public void mouseReleased(ImagePlus imp, MouseEvent e) {e.consume();} 17 | 18 | public void mouseClicked(ImagePlus imp, MouseEvent e) {e.consume();} 19 | 20 | public void mouseDragged(ImagePlus imp, MouseEvent e) {e.consume();} 21 | 22 | public void mouseMoved(ImagePlus imp, MouseEvent e) { } 23 | 24 | public void mouseEntered(ImagePlus imp, MouseEvent e) {e.consume();} 25 | 26 | public void mouseExited(ImagePlus imp, MouseEvent e) {e.consume();} 27 | 28 | public void showPopupMenu(MouseEvent e, Toolbar tb) { } 29 | 30 | /** Return the tool name. */ 31 | public String getToolName() { 32 | return getClass().getName().replace('_', ' '); 33 | } 34 | 35 | /** Return the string encoding of the tool icon. See 36 | http://rsb.info.net/ij/developer/macro/macros.html#icons 37 | The default icon is the first letter of the tool name. 38 | */ 39 | public String getToolIcon() { 40 | String letter = getToolName(); 41 | if (letter!=null && letter.length()>0) 42 | letter = letter.substring(0,1); 43 | else 44 | letter = "P"; 45 | return "C037T5f16"+letter; 46 | } 47 | 48 | public void showOptionsDialog() { 49 | } 50 | 51 | /** These methods are overridden by MacroToolRunner. */ 52 | public void runMacroTool(String name) { } 53 | public void runMenuTool(String name, String command) { } 54 | public Program getMacroProgram() {return null;} 55 | 56 | } 57 | -------------------------------------------------------------------------------- /ij/process/Blitter.java: -------------------------------------------------------------------------------- 1 | package ij.process; 2 | import java.awt.Color; 3 | 4 | /** ImageJ bit blitting classes must implement this interface. */ 5 | public interface Blitter { 6 | 7 | /** dst=src */ 8 | public static final int COPY = 0; 9 | 10 | /** dst=255-src (8-bits and RGB) */ 11 | public static final int COPY_INVERTED = 1; 12 | 13 | /** Copies with white pixels transparent. */ 14 | public static final int COPY_TRANSPARENT = 2; 15 | 16 | /** dst=dst+src */ 17 | public static final int ADD = 3; 18 | 19 | /** dst=dst-src */ 20 | public static final int SUBTRACT = 4; 21 | 22 | /** dst=src*src */ 23 | public static final int MULTIPLY = 5; 24 | 25 | /** dst=dst/src */ 26 | public static final int DIVIDE = 6; 27 | 28 | /** dst=(dst+src)/2 */ 29 | public static final int AVERAGE = 7; 30 | 31 | /** dst=abs(dst-src) */ 32 | public static final int DIFFERENCE = 8; 33 | 34 | /** dst=dst AND src */ 35 | public static final int AND = 9; 36 | 37 | /** dst=dst OR src */ 38 | public static final int OR = 10; 39 | 40 | /** dst=dst XOR src */ 41 | public static final int XOR = 11; 42 | 43 | /** dst=min(dst,src) */ 44 | public static final int MIN = 12; 45 | 46 | /** dst=max(dst,src) */ 47 | public static final int MAX = 13; 48 | 49 | /** Copies with zero pixels transparent. */ 50 | public static final int COPY_ZERO_TRANSPARENT = 14; 51 | 52 | 53 | /** Sets the transparent color used in the COPY_TRANSPARENT 54 | mode (default is Color.white). */ 55 | public void setTransparentColor(Color c); 56 | 57 | /** Copies the image in 'src' to (x,y) using the specified mode. */ 58 | public void copyBits(ImageProcessor src, int x, int y, int mode); 59 | 60 | } 61 | -------------------------------------------------------------------------------- /ij/util/FontUtil.java: -------------------------------------------------------------------------------- 1 | package ij.util; 2 | import java.text.*; 3 | import java.awt.*; 4 | 5 | /** This class contains static utility methods for replacing fonts that are not available on the 6 | * current system. 7 | */ 8 | 9 | public class FontUtil { 10 | 11 | /** Returns a font with the given family name or, if not available, a similar font, e.g. Helvetica replaced by Arial */ 12 | public static Font getFont(String fontFamilyName, int style, float size) { 13 | Font font = new Font(fontFamilyName, style, (int)size); 14 | if (!font.getFamily().startsWith(fontFamilyName)) { 15 | String[] similarFonts = getSimilarFontsList(fontFamilyName); 16 | font = getFont(similarFonts, style, (int)size); 17 | } 18 | if (size != (int)size) 19 | font = font.deriveFont(size); 20 | return font; 21 | } 22 | 23 | /** Returns the font for first element of the 'fontNames' array, where a Font Family Name starts with this name. 24 | * E.g. if fontNames = {"Times New Roman", "Serif" and the system has no "Times New Roman", but finds "Serif", 25 | * it would return a "Serif" font with suitable style and size */ 26 | private static Font getFont(String[] fontNames, int style, int size) { 27 | int iSize = (int)size; 28 | Font font = null; 29 | for (String fontName : fontNames) { 30 | font = new Font(fontName, style, iSize); 31 | if (font.getFamily().startsWith(fontName)) 32 | break; 33 | } 34 | return font; 35 | } 36 | 37 | /** For a few basic font types, gets a list of replacement font families 38 | * Note that java's 'SansSerif' has wider characters (significantly different metrics) than the other 39 | * sans-serif fonts in the list; thus it should be considered a fallback option only. 40 | * Also note that some fonts (Times, Helvetica, Courier, Monospace, Serif) tend to truncate some 41 | * diacritical marks when using FontMetrics.getHeight (as ImageJ does), e.g. the ring of the 42 | * Angstrom symbol Å may be clipped (at least on Java 1.6/Mac) 43 | */ 44 | public static String[] getSimilarFontsList(String fontFamily) { 45 | if (fontFamily.indexOf("Times")>=0 || fontFamily.indexOf("Serif")>=0) 46 | return new String[]{"Times New Roman", "Times", "Liberation Serif", "Serif"}; 47 | else if (fontFamily.indexOf("Arial")>=0 || fontFamily.indexOf("Helvetica")>=0 || fontFamily.indexOf("Sans")>=0) 48 | return new String[]{"Arial", "Helvetica", "Helvetica Neue", "Liberation Sans", "SansSerif"}; 49 | else if (fontFamily.indexOf("Courier")>=0 || fontFamily.indexOf("Mono")>=0) 50 | return new String[]{"Courier New", "Courier", "Liberation Mono", "Monospaced"}; 51 | else 52 | return new String[]{fontFamily}; 53 | } 54 | 55 | 56 | } 57 | -------------------------------------------------------------------------------- /ij/util/IJMath.java: -------------------------------------------------------------------------------- 1 | package ij.util; 2 | 3 | public class IJMath { 4 | 5 | static double A = 0.05857895078654250866288; 6 | static double B = -0.00626245895772819579; 7 | static double C = -0.00299946450696036814; 8 | static double D = 0.289389696496082416; 9 | static double E = 0.0539962589851632982; 10 | static double F = 0.00508516909930653109; 11 | static double G = 0.000215969713046142876; 12 | static double H = -0.000225663858340491571; 13 | static double I = -3.06833213472529049e-7; 14 | 15 | /* This approximation of the error function erf has maximum absolute and relative errors below 1e-12 16 | * Except for low and high x, it is based on the type erf(x) = sgn(x) * sqrt(1-exp(-x^2*f(x)), 17 | * with the function f(x) having a smooth transition from 4/pi = 1.273... at x=0 to 1 at high x */ 18 | public static double erf(double x) { 19 | double x2 = sqr(x); 20 | if (x2 < 1e-8) 21 | return (2/Math.sqrt(Math.PI))*x*(1+x2*(-1./3.+x2*(1./10.))); // Taylor series for low x 22 | double erf = x2 > 36 ? 1 : //the polynomials go crazy for some large x2; erf(6) is 1 - 2e-17, less than ulp from 1 23 | Math.sqrt(1 - Math.exp(-sqr(x*((2/Math.sqrt(Math.PI) - A) + A * 24 | (1 + x2*x2*(B + x2*(C + x2*(H + x2*I)))) / 25 | (1 + x2*(D + x2*(E + x2*(F + x2*G)))) 26 | )))); 27 | return x>0 ? erf : -erf; //could be Math.copySign in Java 1.6 & up 28 | } 29 | 30 | static double sqr(double x) { 31 | return x*x; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /ij/util/Java2.java: -------------------------------------------------------------------------------- 1 | package ij.util; 2 | import ij.*; 3 | import ij.Prefs; 4 | import java.awt.*; 5 | import javax.swing.*; 6 | 7 | /** 8 | This class contains static methods that use the Java 2 API. They are isolated 9 | here to prevent errors when ImageJ is running on Java 1.1 JVMs. 10 | */ 11 | public class Java2 { 12 | 13 | public static void setAntialiased(Graphics g, boolean antialiased) { 14 | Graphics2D g2d = (Graphics2D)g; 15 | if (antialiased) 16 | g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 17 | else 18 | g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); 19 | } 20 | 21 | public static void setAntialiasedText(Graphics g, boolean antialiasedText) { 22 | Graphics2D g2d = (Graphics2D)g; 23 | if (antialiasedText) { 24 | //if (IJ.isMacOSX()) 25 | // g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); 26 | g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB); 27 | } else 28 | g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF); 29 | } 30 | 31 | public static int getStringWidth(String s, FontMetrics fontMetrics, Graphics g) { 32 | java.awt.geom.Rectangle2D r = fontMetrics.getStringBounds(s, g); 33 | return (int)r.getWidth(); 34 | } 35 | 36 | public static void setBilinearInterpolation(Graphics g, boolean bilinearInterpolation) { 37 | Graphics2D g2d = (Graphics2D)g; 38 | if (bilinearInterpolation) 39 | g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); 40 | else 41 | g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR); 42 | } 43 | 44 | /** Sets the Swing look and feel to the system look and feel (Windows only). */ 45 | public static void setSystemLookAndFeel() { 46 | if (!IJ.isWindows()) 47 | return; 48 | try { 49 | UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 50 | } catch(Throwable t) {} 51 | } 52 | 53 | /** Sets the Swing look and feel. */ 54 | public static void setLookAndFeel(LookAndFeel newLookAndFeel) { 55 | if (!IJ.isWindows() || newLookAndFeel==null) 56 | return; 57 | try { 58 | UIManager.setLookAndFeel(newLookAndFeel); 59 | } catch(Throwable t) {} 60 | } 61 | 62 | /** Returns the current Swing look and feel or null. */ 63 | public static LookAndFeel getLookAndFeel() { 64 | if (!IJ.isWindows()) 65 | return null; 66 | return UIManager.getLookAndFeel(); 67 | } 68 | 69 | 70 | } 71 | 72 | -------------------------------------------------------------------------------- /images/about.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagej/ImageJ/4f42db31349086e838edc2ee855fff56c5307e42/images/about.jpg -------------------------------------------------------------------------------- /images/microscope.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagej/ImageJ/4f42db31349086e838edc2ee855fff56c5307e42/images/microscope.gif -------------------------------------------------------------------------------- /macros/AddParticles.txt: -------------------------------------------------------------------------------- 1 | // Adds particle analyzer ROIs to the ROI Manager 2 | if (nResults==0) 3 | return "Results table is empty"; 4 | if (isNaN(getResult('XStart', 0))) 5 | return "Run the particle analyzer with \"Clear Results\" \nand \"Record Starts\" checked, then try again."; 6 | for (i=0; iInstall Macros) to reinstall after 3 | // making changes. Double click on the tool icon (a circle) 4 | // to set the radius of the circle. 5 | // There is more information about macro tools at 6 | // http://imagej.nih.gov/ij/developer/macro/macros.html#tools 7 | // and many more examples at 8 | // http://imagej.nih.gov/ij/macros/tools/ 9 | 10 | var radius = 20; 11 | 12 | macro "Circle Tool - C00cO11cc" { 13 | getCursorLoc(x, y, z, flags); 14 | makeOval(x-radius, y-radius, radius*2, radius*2); 15 | } 16 | 17 | macro "Circle Tool Options" { 18 | radius = getNumber("Radius: ", radius); 19 | } 20 | -------------------------------------------------------------------------------- /macros/CommandFinderTool.txt: -------------------------------------------------------------------------------- 1 | macro "Command Finder Action Tool - C037T0e17CTce17F" { 2 | run("Find Commands..."); 3 | } 4 | 5 | -------------------------------------------------------------------------------- /macros/ConvertStackToBinary.txt: -------------------------------------------------------------------------------- 1 | // Converts a stack to binary using locally calculated thresholds 2 | 3 | setBatchMode(true); 4 | run("Select None"); 5 | run("8-bit"); 6 | id = getImageID; 7 | for (i=1; i<=nSlices; i++) { 8 | setSlice(i); 9 | run("Duplicate...", "title=temp"); 10 | run("Convert to Mask"); 11 | invertingLUT = is("Inverting LUT"); 12 | run("Copy"); 13 | close; 14 | selectImage(id); 15 | run("Paste"); 16 | if (i==1 && invertingLUT != is("Inverting LUT")) 17 | run("Invert LUT"); 18 | } 19 | run("Select None"); 20 | -------------------------------------------------------------------------------- /macros/DeveloperMenuTool.txt: -------------------------------------------------------------------------------- 1 | var dCmds = newMenu("Developer Menu Tool", 2 | newArray("Record...", "Capture Screen ", "Monitor Memory...", "Find Commands...", 3 | "Search...", "ImageJ Properties", "List Elements", "Debug Mode", "ImageJ Website...", 4 | "-", "Image...", "Hyperstack...", "Macro", "Open...", 5 | "-", "Blobs", "Fly Brain", "HeLa Cells (48-bit RGB)", "Image with Overlay", 6 | "Mitosis (5D stack)", "T1 Head (16-bits)")); 7 | 8 | macro "Developer Menu Tool - C037T0b14DT9b12eTfb12v" { 9 | cmd = getArgument(); 10 | if (cmd=="Debug Mode") 11 | setOption("DebugMode", true); 12 | else if (cmd!="-") 13 | run(cmd); 14 | } 15 | -------------------------------------------------------------------------------- /macros/Filter_Plugin.src: -------------------------------------------------------------------------------- 1 | import ij.*; 2 | import ij.process.*; 3 | import ij.gui.*; 4 | import java.awt.*; 5 | import ij.plugin.filter.*; 6 | 7 | public class Filter_Plugin implements PlugInFilter { 8 | ImagePlus imp; 9 | 10 | public int setup(String arg, ImagePlus imp) { 11 | this.imp = imp; 12 | return DOES_ALL; 13 | } 14 | 15 | public void run(ImageProcessor ip) { 16 | ip.invert(); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /macros/FloodFillTool.txt: -------------------------------------------------------------------------------- 1 | var floodType = call("ij.Prefs.get", "tool.flood", "8-connected"); 2 | var alt = 8; 3 | 4 | macro "Flood Fill Tool -C037B21P085373b75d0L4d1aL3135L4050L6166D57D77D68D09D94Da7C123Da5La9abLb6bc" { 5 | setupUndo(); 6 | getCursorLoc(x, y, z, flags); 7 | if (flags&alt!=0) 8 | setColor(getValue("color.background")); 9 | floodFill(x, y, floodType); 10 | } 11 | 12 | macro 'Flood Fill Tool Options...' { 13 | Dialog.create("Flood Fill Tool"); 14 | Dialog.addChoice("Flood Type:", newArray("4-connected", "8-connected"), floodType); 15 | Dialog.show(); 16 | floodType = Dialog.getChoice(); 17 | call("ij.Prefs.set", "tool.flood", floodType); 18 | } 19 | -------------------------------------------------------------------------------- /macros/InvertAllLuts.txt: -------------------------------------------------------------------------------- 1 | // "Invert all LUTs" 2 | // Converts all LUTs in a multi-channel image between 3 | // inverted and non inverted and switches the 4 | // composite rendering mode accordingly. 5 | // Author: Kevin Terretaz 6 | // Contributor: Nicolás De Francesco 7 | 8 | requires("1.53o"); 9 | getDimensions(width, height, channels, slices, frames); 10 | REDS = newArray(256); 11 | GREENS = newArray(256); 12 | BLUES = newArray(256); 13 | for (c=1; c<=channels; c++) { 14 | Stack.setChannel(c); 15 | getLut(reds,greens,blues); 16 | for (i=0; i<256; i++) { 17 | hsv = HSV_from_RGB(255-reds[i], 255-greens[i], 255-blues[i]); 18 | hsv[0] = (hsv[0]+128)%256; 19 | rgb = RGB_from_HSV(hsv[0], hsv[1], hsv[2]); 20 | REDS[i] = round(rgb[0]); 21 | GREENS[i] = round(rgb[1]); 22 | BLUES[i] = round(rgb[2]); 23 | } 24 | setLut(REDS, GREENS, BLUES); 25 | } 26 | 27 | Stack.setChannel(1); 28 | // CompositeProjection mode switch : 29 | mode = Property.get("CompositeProjection"); 30 | if (is("Inverting LUT")&&(mode=="Min"||mode=="Invert")) 31 | ; // do nothing 32 | else if (!is("Inverting LUT")&&(mode=="Sum"||mode=="Max")) 33 | ; // do nothing 34 | else if (mode=="Invert") 35 | Property.set("CompositeProjection", "Sum"); 36 | else if (mode=="Min") 37 | Property.set("CompositeProjection", "Max"); 38 | else if (mode=="Max") 39 | Property.set("CompositeProjection", "Min"); 40 | else // if Composite Sum 41 | Property.set("CompositeProjection", "Invert"); 42 | updateDisplay(); 43 | 44 | function HSV_from_RGB(r, g, b) { 45 | // adapted from https://en.wikipedia.org/wiki/HSL_and_HSV#From_RGB 46 | v = maxOf(r, maxOf(g, b)); // value (brightness) 47 | c = v - minOf(r, minOf(g, b)); // chroma 48 | h = 0; 49 | if (c>0) { 50 | if (v==r) h = 256/6 * (0 + g-b)/c; 51 | if (v==g) h = 256/6 * (2 + (b-r)/c); 52 | if (v==b) h = 256/6 * (4 + (r-g)/c); 53 | } 54 | h = (h+256)%256; 55 | s = 0; 56 | if (v>0) s = c/v*256; 57 | hsv = newArray(h, s, v); 58 | return hsv; 59 | } 60 | 61 | function RGB_from_HSV(h, s, v) { 62 | // adapted from https://en.wikipedia.org/wiki/HSL_and_HSV#HSV_to_RGB_alternative 63 | r = v - v * s / 256 * maxOf(0, minOf((5+h/256*6)%6, minOf(4-(5+h/256*6)%6, 1))); 64 | g = v - v * s / 256 * maxOf(0, minOf((3+h/256*6)%6, minOf(4-(3+h/256*6)%6, 1))); 65 | b = v - v * s / 256 * maxOf(0, minOf((1+h/256*6)%6, minOf(4-(1+h/256*6)%6, 1))); 66 | rgb = newArray(r, g, b); 67 | return rgb; 68 | } 69 | -------------------------------------------------------------------------------- /macros/LUTMenuTool.txt: -------------------------------------------------------------------------------- 1 | var lutdir = getDirectory("startup")+"luts"+File.separator; 2 | var luts = getLutMenu(); 3 | var lCmds = newMenu("LUT Menu Tool", luts); 4 | 5 | macro "LUT Menu Tool - C037T0b10LT6b10UTeb10T" { 6 | cmd = getArgument(); 7 | if (cmd!="-") run(cmd); 8 | } 9 | 10 | function getLutMenu() { 11 | list = getList("LUTs"); 12 | menu = newArray(3+list.length); 13 | menu[0] = "Invert LUT"; 14 | menu[1] = "Apply LUT"; 15 | menu[2] = "-"; 16 | for (i=0; i1 || width!=globalLineWidth) { 12 | lineWidth=width; 13 | globalLineWidth = width; 14 | } 15 | radius = maxOf(4,lineWidth*2); 16 | getCursorLoc(x, y, z, flags); 17 | if (flags&9>0) { // shift or alt 18 | removeLabel(x,y); 19 | exit(); 20 | } 21 | getDateAndTime(yr, mo, dw, d, h, m, s, ms); 22 | uid = "labeltool_"+yr+""+mo+""+d+""+h+""+m+""+s+""+ms; 23 | nbefore = Overlay.size; 24 | getCursorLoc(x1, y1, z, flags); 25 | setLineWidth(lineWidth); 26 | while (flags&16>0) { 27 | getCursorLoc(x1, y1, z, flags); 28 | drawItem(); 29 | wait(30); 30 | while (Overlay.size>nbefore) 31 | Overlay.removeSelection(Overlay.size-1); 32 | } 33 | drawItem(); 34 | label =getString("Enter label", label); 35 | while (Overlay.size>nbefore) 36 | Overlay.removeSelection(Overlay.size-1); 37 | drawItem(); 38 | } 39 | 40 | function drawItem() { 41 | makeOval(x-radius, y-radius, radius*2, radius*2); 42 | Roi.setName(uid); 43 | Overlay.addSelection("",0,""+hexCol()); 44 | makeLine(x, y,x1,y1,x1+(((x1=x)*1))*getStringWidth(label),y1); 45 | Roi.setName(uid); 46 | Overlay.addSelection(""+hexCol(), lineWidth); 47 | setFont("user"); 48 | makeText(label, x1 - (x1=0) { 61 | Overlay.activateSelection(index); 62 | name = Roi.getName(); 63 | Overlay.removeRois(name); 64 | Roi.remove; 65 | } 66 | } 67 | 68 | macro "Label Tool (double click for options) Options" { 69 | Dialog.create("Label Maker Tool Options"); 70 | Dialog.addNumber("Line width:", lineWidth, 0, 3, "pixels"); 71 | m1 = "Shift or alt click to remove a label.\n"; 72 | m2 = "Double click on text tool to change\n"; 73 | m3 = "font size and color."; 74 | Dialog.setInsets(0, 0, 0); 75 | Dialog.addMessage(m1+m2+m3); 76 | Dialog.show(); 77 | lineWidth = Dialog.getNumber(); 78 | } 79 | 80 | -------------------------------------------------------------------------------- /macros/MoveSelection.txt: -------------------------------------------------------------------------------- 1 | // Moves the selection left and down a specified distance in pixels. 2 | 3 | xy = split(getArgument()); 4 | if (lengthOf(xy)!=2) { 5 | dx = 10; 6 | dy = 10; 7 | } else { 8 | dx = parseFloat(xy[0]); 9 | if (isNaN(dx)) dx = 10; 10 | dy = parseFloat(xy[1]); 11 | if (isNaN(dy)) dy = 10; 12 | } 13 | getPixelSize(unit, pixelWidth, pixelHeight); 14 | if (unit=="pixel") unit = "pixels"; 15 | dxc = dx*pixelWidth; 16 | dyc = dy*pixelHeight; 17 | Dialog.create("Move"); 18 | Dialog.addNumber("Delta_X ("+unit+"):", dxc); 19 | Dialog.addNumber("Delta_Y ("+unit+"):", dyc); 20 | Dialog.show(); 21 | dx = Dialog.getNumber()/pixelWidth; 22 | dy = Dialog.getNumber()/pixelHeight; 23 | moveSelection(dx, dy); 24 | return toString(dx)+" "+toString(dy); 25 | 26 | function moveSelection(dx, dy) { 27 | getBoundingRect(x, y, width, height); 28 | if (selectionType==0) 29 | makeRectangle(x+dx, y+dy, width, height); 30 | else if (selectionType==1) 31 | makeOval(x+dx, y+dy, width, height); 32 | else { 33 | getSelectionCoordinates(xCoordinates, yCoordinates); 34 | for (i=0; iLookup Tables menu. 3 | 4 | saveSettings(); 5 | list = getList("LUTs"); 6 | setBatchMode(true); 7 | newImage("ramp", "8-bit Ramp", 256, 32, 1); 8 | newImage("luts", "RGB White", 256, 48, 1); 9 | count = 0; 10 | setForegroundColor(255, 255, 255); 11 | setBackgroundColor(255, 255, 255); 12 | setFont("SansSerif", 12,"antialiased"); 13 | for (i=0; i 1 px"); 10 | if (selectionType != 4) 11 | exit("No traced selection found"); 12 | getThreshold(lowThr, hiThr); 13 | getSelectionCoordinates(xx, yy); 14 | len = xx.length; 15 | polyX = newArray(len); 16 | polyY = newArray(len); 17 | count = 0; 18 | for(jj = 0; jj < len; jj++) { 19 | x1 = xx[jj]; 20 | y1 = yy[jj]; 21 | x2 = xx[(jj+1)%len]; 22 | y2 = yy[(jj+1)%len]; 23 | dd = 1; 24 | if (y1 == y2) {//horizontal separator 25 | if (x1 > x2) dd = -1; 26 | for(x = x1; x != x2; x+= dd){ 27 | processPixelPair(x, y1, x+dd, y1); 28 | } 29 | } 30 | else {//vertical separator 31 | if (y1 > y2) dd = -1; 32 | for(y = y1; y != y2; y+= dd){ 33 | processPixelPair(x1, y, x1, y+dd); 34 | } 35 | } 36 | } 37 | polyX = Array.trim(polyX, count); 38 | polyY = Array.trim(polyY, count); 39 | makeSelection("polygon", polyX, polyY); 40 | run("Interpolate", "interval=1 adjust"); //after button released 41 | 42 | //processes neighbors of this separator line and adds vertex 43 | function processPixelPair(x1, y1, x2, y2) { 44 | if (x1 == x2) { 45 | val1 = getPixel(x1, minOf(y1, y2)); 46 | val2 = getPixel(x1 - 1, minOf(y1, y2)); 47 | } 48 | if (y1 == y2){ 49 | val1 = getPixel(minOf(x1, x2), y1); 50 | val2 = getPixel(minOf(x1, x2), y1 -1); 51 | } 52 | bright = maxOf(val1, val2); 53 | dark = minOf(val1, val2); 54 | 55 | if (bright>=lowThr && dark<=lowThr) 56 | thr = lowThr; 57 | if (bright>=hiThr && dark<=hiThr) 58 | thr = hiThr; 59 | if (dark==bright) 60 | fraction = 0.5; 61 | else 62 | fraction = (thr - dark)/(bright - dark); 63 | if (val1 < val2) 64 | fraction = 1 - fraction; 65 | if (y1 == y2) { 66 | newY = minOf(y1, y2) + fraction - 0.5; 67 | newX = (x1 + x2)/2; 68 | } 69 | if (x1 == x2) { 70 | newX = minOf(x1, x2) + fraction - 0.5; 71 | newY = (y1 + y2)/2; 72 | } 73 | polyX[count] = newX; 74 | polyY[count] = newY; 75 | count++; 76 | if (count == polyX.length){ 77 | polyX = Array.concat(polyX, polyX); 78 | polyY = Array.concat(polyY, polyY); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /macros/SprayCanTool.txt: -------------------------------------------------------------------------------- 1 | // Spray Can Tool 2 | 3 | var width=100, dotSize=1, rate=6; 4 | 5 | macro 'Spray Can Tool - C123D20D22D24D41D43D62D82Da2C037L93b3D84Dc4L75d5L757f Ld5dfLa7d7LabdbLa9d9LacdcLa7ac' { 6 | setLineWidth(dotSize); 7 | radius=width/2; radius2=radius*radius; 8 | start = getTime(); 9 | autoUpdate(false); 10 | n = 25*exp(0.9*(10-rate)); 11 | if (n<=5) n = 0; 12 | while (true) { 13 | getCursorLoc(x, y, z, flags); 14 | if (flags&16==0) exit(); 15 | x2 = (random()-0.5)*width; 16 | y2 = (random()-0.5)*width; 17 | if (x2*x2+y2*y2start+50) { 22 | updateDisplay(); 23 | start = getTime(); 24 | } 25 | } 26 | for (i=0; i10) rate = 10; 41 | } 42 | -------------------------------------------------------------------------------- /macros/StacksMenuTool.txt: -------------------------------------------------------------------------------- 1 | var sCmds = newMenu("Stacks Menu Tool", 2 | newArray("Add Slice", "Delete Slice", "Set Slice...", 3 | "-", "3D Project...", "Grouped Z Project...", "Z Project...", "Orthogonal Views", "Plot Z-axis Profile", "Reslice [/]...", 4 | "-", "Images to Stack", "Stack to Images", "Make Montage...", 5 | "-", "Make Substack...", "Stack to Hyperstack...", 6 | "-", "Combine...", "Concatenate...", "Flip Z", "Label...", "Animation Options...", 7 | "-", "T1 Head (2.4M, 16-bits)")); 8 | 9 | macro "Stacks Menu Tool - C037T0b11ST8b09tTcb09k" { 10 | cmd = getArgument(); 11 | if (cmd=="Images to Stack") 12 | run(cmd, " "); 13 | else if (cmd!="-") 14 | run(cmd); 15 | } 16 | -------------------------------------------------------------------------------- /macros/StartupMacros.txt: -------------------------------------------------------------------------------- 1 | // Default startup macros 2 | 3 | macro "Developer Menu Built-in Tool" {} 4 | macro "Brush Built-in Tool" {} 5 | macro "Flood Filler Built-in Tool" {} 6 | macro "Arrow Built-in Tool" {} 7 | 8 | -------------------------------------------------------------------------------- /macros/TimeStamp.ijm: -------------------------------------------------------------------------------- 1 | x=20; y=30; size=18; 2 | interval=1; //seconds 3 | i = floor(i*interval); // 'i' is the image index 4 | setFont("SansSerif", size, "antialiased"); 5 | setColor("white"); 6 | s = ""+pad(floor(i/3600))+":"+pad(floor((i/60)%60))+":"+pad(i%60); 7 | drawString(s, x, y); 8 | function pad(n) { 9 | str = toString(n); 10 | if (lengthOf(str)==1) str="0"+str; 11 | return str; 12 | } 13 | 14 | -------------------------------------------------------------------------------- /module-info.java: -------------------------------------------------------------------------------- 1 | module ij { 2 | requires java.desktop; 3 | requires java.rmi; 4 | requires java.compiler; 5 | requires java.scripting; 6 | exports ij; 7 | exports ij.gui; 8 | exports ij.io; 9 | exports ij.macro; 10 | exports ij.measure; 11 | exports ij.plugin; 12 | exports ij.plugin.filter; 13 | exports ij.plugin.frame; 14 | exports ij.plugin.tool; 15 | exports ij.process; 16 | exports ij.text; 17 | exports ij.util; 18 | } -------------------------------------------------------------------------------- /nbproject/genfiles.properties: -------------------------------------------------------------------------------- 1 | build.xml.data.CRC32=19922061 2 | build.xml.script.CRC32=ecedc6c9 3 | build.xml.stylesheet.CRC32=d5b6853a 4 | # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. 5 | # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. 6 | nbproject/build-impl.xml.data.CRC32=d9d2b1da 7 | nbproject/build-impl.xml.script.CRC32=ba521f9c 8 | nbproject/build-impl.xml.stylesheet.CRC32=d7756595 9 | -------------------------------------------------------------------------------- /nbproject/project.properties: -------------------------------------------------------------------------------- 1 | application.args= 2 | build.classes.dir=${build.dir}/classes 3 | build.classes.excludes=**/*.java,**/*.form 4 | # This directory is removed when the project is cleaned: 5 | build.dir=build 6 | build.generated.dir=${build.dir}/generated 7 | # Only compile against the classpath explicitly listed here: 8 | build.sysclasspath=ignore 9 | build.test.classes.dir=${build.dir}/test/classes 10 | build.test.results.dir=${build.dir}/test/results 11 | debug.classpath=\ 12 | ${run.classpath} 13 | debug.test.classpath=\ 14 | ${run.test.classpath} 15 | # This directory is removed when the project is cleaned: 16 | dist.dir=dist 17 | dist.jar=${dist.dir}/imagej.jar 18 | dist.javadoc.dir=${dist.dir}/javadoc 19 | file.reference.SteveM-imageja=. 20 | jar.compress=false 21 | javac.classpath= 22 | # Space-separated list of extra javac options 23 | javac.compilerargs= 24 | javac.deprecation=false 25 | javac.source=${default.javac.source} 26 | javac.target=${default.javac.target} 27 | javac.test.classpath=\ 28 | ${javac.classpath}:\ 29 | ${build.classes.dir}:\ 30 | ${libs.junit.classpath} 31 | javadoc.additionalparam= 32 | javadoc.author=false 33 | javadoc.encoding= 34 | javadoc.noindex=false 35 | javadoc.nonavbar=false 36 | javadoc.notree=false 37 | javadoc.private=false 38 | javadoc.splitindex=true 39 | javadoc.use=true 40 | javadoc.version=false 41 | javadoc.windowtitle= 42 | main.class=imagej.Main 43 | manifest.file=manifest.mf 44 | meta.inf.dir=${src.dir}/META-INF 45 | platform.active=default_platform 46 | run.classpath=\ 47 | ${javac.classpath}:\ 48 | ${build.classes.dir} 49 | # Space-separated list of JVM arguments used when running the project 50 | # (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value 51 | # or test-sys-prop.name=value to set system properties for unit tests): 52 | run.jvmargs= 53 | run.test.classpath=\ 54 | ${javac.test.classpath}:\ 55 | ${build.test.classes.dir} 56 | src.imageja.dir=${file.reference.SteveM-imageja} 57 | test.src.dir=test 58 | -------------------------------------------------------------------------------- /nbproject/project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | org.netbeans.modules.java.j2seproject 4 | 5 | 6 | 7 | imagej 8 | 1.6.5 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /plugins/MacAdapter.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagej/ImageJ/4f42db31349086e838edc2ee855fff56c5307e42/plugins/MacAdapter.class -------------------------------------------------------------------------------- /plugins/MacAdapter.source: -------------------------------------------------------------------------------- 1 | package ij.plugin; 2 | import ij.plugin.*; 3 | import ij.*; 4 | import ij.io.*; 5 | import com.apple.eawt.*; 6 | import java.util.Vector; 7 | 8 | /** This Mac-specific plugin is designed to handle the “About ImageJ", 9 | Preferences and “Quit ImageJ" commands in the ImageJ menu, and to 10 | open files dropped on ImageJ.app and to open double-clicked files 11 | with creator code "imgJ". With Java 8, the “About ImageJ" and 12 | “Quit ImageJ” commands work without MacAdapter. 13 | */ 14 | public class MacAdapter implements PlugIn, ApplicationListener, Runnable { 15 | static Vector paths = new Vector(); 16 | 17 | public void run(String arg) { 18 | Application app = new Application(); 19 | app.setEnabledPreferencesMenu(true); 20 | app.addApplicationListener(this); 21 | } 22 | 23 | public void handleAbout(ApplicationEvent event) { 24 | IJ.doCommand("About ImageJ..."); 25 | event.setHandled(true); 26 | } 27 | 28 | public void handleOpenFile(ApplicationEvent event) { 29 | paths.add(event.getFilename()); 30 | Thread thread = new Thread(this, "Open"); 31 | thread.setPriority(thread.getPriority()-1); 32 | thread.start(); 33 | } 34 | 35 | public void handlePreferences(ApplicationEvent event) { 36 | IJ.error("The ImageJ preferences are in the Edit>Options menu."); 37 | } 38 | 39 | public void handleQuit(ApplicationEvent event) { 40 | new Executer("Quit", null); // works with the CommandListener 41 | //IJ.getInstance().quit(); 42 | } 43 | 44 | public void run() { 45 | if (paths.size() > 0) { 46 | (new Opener()).openAndAddToRecent((String) paths.remove(0)); 47 | } 48 | } 49 | 50 | public void handleOpenApplication(ApplicationEvent event) {} 51 | public void handleReOpenApplication(ApplicationEvent event) {} 52 | public void handlePrintFile(ApplicationEvent event) {} 53 | 54 | } 55 | -------------------------------------------------------------------------------- /plugins/MacAdapter9.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagej/ImageJ/4f42db31349086e838edc2ee855fff56c5307e42/plugins/MacAdapter9.class -------------------------------------------------------------------------------- /plugins/MacAdapter9.source: -------------------------------------------------------------------------------- 1 | package ij.plugin; 2 | import ij.*; 3 | import ij.io.*; 4 | import java.awt.Desktop; 5 | import java.awt.desktop.*; 6 | import java.io.File; 7 | import java.util.Vector; 8 | 9 | /** This Mac-specific plugin is designed to handle the "About ImageJ" 10 | * command in the ImageJ menu, to open files dropped on ImageJ.app 11 | * and to open double-clicked files with creator code "imgJ". 12 | * With Java 9 or newer, we use java.awt.desktop instead of the 13 | * previous com.apple.eawt.* classes. 14 | * @author Alan Brooks 15 | */ 16 | public class MacAdapter9 implements PlugIn, AboutHandler, OpenFilesHandler, QuitHandler, Runnable { 17 | static Vector paths = new Vector(); 18 | 19 | public void run(String arg) { 20 | Desktop dtop = Desktop.getDesktop(); 21 | dtop.setOpenFileHandler(this); 22 | dtop.setAboutHandler(this); 23 | dtop.setQuitHandler(this); 24 | } 25 | 26 | @Override 27 | public void handleAbout(AboutEvent e) { 28 | IJ.doCommand("About ImageJ..."); 29 | } 30 | 31 | @Override 32 | public void openFiles(OpenFilesEvent e) { 33 | for (File file: e.getFiles()) { 34 | paths.add(file.getPath()); 35 | Thread thread = new Thread(this, "Open"); 36 | thread.setPriority(thread.getPriority()-1); 37 | thread.start(); 38 | } 39 | } 40 | 41 | @Override 42 | public void handleQuitRequestWith(QuitEvent e, QuitResponse response) { 43 | new Executer("Quit", null); // works with the CommandListener 44 | } 45 | 46 | // Not adding preference handling 47 | // because we don't have the equivalent of app.setEnabledPreferencesMenu(true); 48 | // @Override 49 | // public void handlePreferences(PreferencesEvent e) { 50 | // IJ.error("The ImageJ preferences are in the Edit>Options menu."); 51 | // } 52 | 53 | public void run() { 54 | if (paths.size() > 0) { 55 | (new Opener()).openAndAddToRecent(paths.remove(0)); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /policy: -------------------------------------------------------------------------------- 1 | 2 | grant { 3 | 4 | // Allow everything for now 5 | 6 | permission java.security.AllPermission; 7 | }; 8 | 9 | -------------------------------------------------------------------------------- /run_appletviewer.bat: -------------------------------------------------------------------------------- 1 | 2 | appletviewer -J-Djava.security.policy=policy applet.html 3 | 4 | pause 5 | -------------------------------------------------------------------------------- /tests/data/01.dcm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagej/ImageJ/4f42db31349086e838edc2ee855fff56c5307e42/tests/data/01.dcm -------------------------------------------------------------------------------- /tests/data/BasicTable.txt: -------------------------------------------------------------------------------- 1 | ,Label,Smiles,Winks,Nods 2 | Fred,Jones,3,5,7 3 | Joe,Bob,1,2,8 -------------------------------------------------------------------------------- /tests/data/BogusTable.txt: -------------------------------------------------------------------------------- 1 | Hello 2 | There 3 | Everybody -------------------------------------------------------------------------------- /tests/data/CardioShort.raw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagej/ImageJ/4f42db31349086e838edc2ee855fff56c5307e42/tests/data/CardioShort.raw -------------------------------------------------------------------------------- /tests/data/Cell_Colony.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagej/ImageJ/4f42db31349086e838edc2ee855fff56c5307e42/tests/data/Cell_Colony.jpg -------------------------------------------------------------------------------- /tests/data/EmptyFile.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagej/ImageJ/4f42db31349086e838edc2ee855fff56c5307e42/tests/data/EmptyFile.txt -------------------------------------------------------------------------------- /tests/data/Tree_Rings.pgm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagej/ImageJ/4f42db31349086e838edc2ee855fff56c5307e42/tests/data/Tree_Rings.pgm -------------------------------------------------------------------------------- /tests/data/bat-cochlea-renderings.fits: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagej/ImageJ/4f42db31349086e838edc2ee855fff56c5307e42/tests/data/bat-cochlea-renderings.fits -------------------------------------------------------------------------------- /tests/data/blobs.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagej/ImageJ/4f42db31349086e838edc2ee855fff56c5307e42/tests/data/blobs.gif -------------------------------------------------------------------------------- /tests/data/clown.raw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagej/ImageJ/4f42db31349086e838edc2ee855fff56c5307e42/tests/data/clown.raw -------------------------------------------------------------------------------- /tests/data/embryos.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagej/ImageJ/4f42db31349086e838edc2ee855fff56c5307e42/tests/data/embryos.bmp -------------------------------------------------------------------------------- /tests/data/fake.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagej/ImageJ/4f42db31349086e838edc2ee855fff56c5307e42/tests/data/fake.gz -------------------------------------------------------------------------------- /tests/data/gray16-3x2-sub1.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagej/ImageJ/4f42db31349086e838edc2ee855fff56c5307e42/tests/data/gray16-3x2-sub1.tif -------------------------------------------------------------------------------- /tests/data/gray16-3x2-sub2.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagej/ImageJ/4f42db31349086e838edc2ee855fff56c5307e42/tests/data/gray16-3x2-sub2.tif -------------------------------------------------------------------------------- /tests/data/gray16.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagej/ImageJ/4f42db31349086e838edc2ee855fff56c5307e42/tests/data/gray16.zip -------------------------------------------------------------------------------- /tests/data/gray16signedA.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagej/ImageJ/4f42db31349086e838edc2ee855fff56c5307e42/tests/data/gray16signedA.tif -------------------------------------------------------------------------------- /tests/data/gray16signedB.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagej/ImageJ/4f42db31349086e838edc2ee855fff56c5307e42/tests/data/gray16signedB.tif -------------------------------------------------------------------------------- /tests/data/gray24-3x2-sub1.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagej/ImageJ/4f42db31349086e838edc2ee855fff56c5307e42/tests/data/gray24-3x2-sub1.tif -------------------------------------------------------------------------------- /tests/data/gray24-3x2-sub2.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagej/ImageJ/4f42db31349086e838edc2ee855fff56c5307e42/tests/data/gray24-3x2-sub2.tif -------------------------------------------------------------------------------- /tests/data/gray32float-3x2-sub1.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagej/ImageJ/4f42db31349086e838edc2ee855fff56c5307e42/tests/data/gray32float-3x2-sub1.tif -------------------------------------------------------------------------------- /tests/data/gray32float-3x2-sub2.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagej/ImageJ/4f42db31349086e838edc2ee855fff56c5307e42/tests/data/gray32float-3x2-sub2.tif -------------------------------------------------------------------------------- /tests/data/gray8-3x2-stack.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagej/ImageJ/4f42db31349086e838edc2ee855fff56c5307e42/tests/data/gray8-3x2-stack.tif -------------------------------------------------------------------------------- /tests/data/gray8-3x2-sub1.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagej/ImageJ/4f42db31349086e838edc2ee855fff56c5307e42/tests/data/gray8-3x2-sub1.tif -------------------------------------------------------------------------------- /tests/data/gray8-3x2-sub2.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagej/ImageJ/4f42db31349086e838edc2ee855fff56c5307e42/tests/data/gray8-3x2-sub2.tif -------------------------------------------------------------------------------- /tests/data/head.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagej/ImageJ/4f42db31349086e838edc2ee855fff56c5307e42/tests/data/head.tif -------------------------------------------------------------------------------- /tests/data/head8bit.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagej/ImageJ/4f42db31349086e838edc2ee855fff56c5307e42/tests/data/head8bit.tif -------------------------------------------------------------------------------- /tests/data/htm_symb_rep.raw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagej/ImageJ/4f42db31349086e838edc2ee855fff56c5307e42/tests/data/htm_symb_rep.raw -------------------------------------------------------------------------------- /tests/data/lena-std.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imagej/ImageJ/4f42db31349086e838edc2ee855fff56c5307e42/tests/data/lena-std.png -------------------------------------------------------------------------------- /tests/ij/ByteCreator.java: -------------------------------------------------------------------------------- 1 | package ij; 2 | 3 | /** 4 | * TODO 5 | * 6 | * @author Barry DeZonia 7 | */ 8 | public class ByteCreator { 9 | 10 | // helper - create a list of bytes in ascending order 11 | public static byte[] ascending(int count) 12 | { 13 | byte[] output = new byte[count]; 14 | for (int i = 0; i < count; i++) 15 | output[i] = (byte)i; 16 | return output; 17 | } 18 | 19 | // helper - create a list of bytes in descending order 20 | public static byte[] descending(int count) 21 | { 22 | byte[] output = new byte[count]; 23 | for (int i = 0; i < count; i++) 24 | output[i] = (byte)(count-i-1); 25 | return output; 26 | } 27 | 28 | // helper - create a list of repeated bytes 29 | public static byte[] repeated(int count, int value) 30 | { 31 | byte[] output = new byte[count]; 32 | for (int i = 0; i < count; i++) 33 | output[i] = (byte)value; 34 | return output; 35 | } 36 | 37 | // helper - create a list of random bytes from 0 .. range-1 38 | public static byte[] random(int count, int range) 39 | { 40 | byte[] output = new byte[count]; 41 | for (int i = 0; i < count; i++) 42 | output[i] = (byte)Math.floor(range*Math.random()); 43 | return output; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /tests/ij/CommandListenerTest.java: -------------------------------------------------------------------------------- 1 | package ij; 2 | 3 | import static org.junit.Assert.assertTrue; 4 | 5 | import org.junit.Test; 6 | 7 | /** 8 | * Unit tests for {@link CommandListener}. 9 | * 10 | * @author Barry DeZonia 11 | */ 12 | public class CommandListenerTest { 13 | 14 | // implement the interface so that we have compile time check it exists 15 | class FakeCL implements CommandListener { 16 | @Override 17 | public String commandExecuting(String command) { return null; } 18 | } 19 | 20 | @Test 21 | public void testExistence() { 22 | assertTrue(true); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /tests/ij/IJEventListenerTest.java: -------------------------------------------------------------------------------- 1 | package ij; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import org.junit.Test; 6 | 7 | /** 8 | * Unit tests for {@link IJEventListener}. 9 | * 10 | * @author Barry DeZonia 11 | */ 12 | public class IJEventListenerTest { 13 | 14 | // implement the interface so that we have compile time check it exists 15 | 16 | class FakeEL implements IJEventListener { 17 | 18 | @Override 19 | public void eventOccurred(int eventID) { 20 | // do nothing 21 | } 22 | } 23 | 24 | @Test 25 | public void testConstants() { 26 | assertEquals(0,IJEventListener.FOREGROUND_COLOR_CHANGED); 27 | assertEquals(1,IJEventListener.BACKGROUND_COLOR_CHANGED); 28 | assertEquals(2,IJEventListener.COLOR_PICKER_CLOSED); 29 | assertEquals(3,IJEventListener.LOG_WINDOW_CLOSED); 30 | assertEquals(4,IJEventListener.TOOL_CHANGED); 31 | } 32 | 33 | @Test 34 | public void testEventOccurred() { 35 | // do nothing 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /tests/ij/IJInfo.java: -------------------------------------------------------------------------------- 1 | package ij; 2 | 3 | /** 4 | * Class to hold various info about underlying IJ. 5 | * 6 | * @author Barry DeZonia 7 | */ 8 | public class IJInfo { 9 | // BDZ: I had an issue where I was generating tests that failed with the original IJ. Rather than comment out the 10 | // tests I have created this constant for runtime checking so that more rigorous tests can be exercised after 11 | // the refactor and when those changed systems have been hardened. Could become a boolean set from the command line. 12 | public static final boolean RUN_ENHANCED_TESTS = false; 13 | 14 | // BDZ: some methods interact with the GUI. Enable the following boolean to run those tests interactively. Could become 15 | // a boolean set from the command line. 16 | public static final boolean RUN_GUI_TESTS = false; 17 | } 18 | -------------------------------------------------------------------------------- /tests/ij/ImageListenerTest.java: -------------------------------------------------------------------------------- 1 | package ij; 2 | 3 | import static org.junit.Assert.assertTrue; 4 | 5 | import org.junit.Test; 6 | 7 | /** 8 | * Unit tests for {@link ImageListener}. 9 | * 10 | * @author Barry DeZonia 11 | */ 12 | public class ImageListenerTest { 13 | 14 | // implement the interface so that we have compile time check it exists 15 | class FakeIL implements ImageListener { 16 | 17 | @Override 18 | public void imageClosed(ImagePlus imp) { 19 | // do nothing 20 | } 21 | 22 | @Override 23 | public void imageOpened(ImagePlus imp) { 24 | // do nothing 25 | } 26 | 27 | @Override 28 | public void imageUpdated(ImagePlus imp) { 29 | // do nothing 30 | } 31 | 32 | } 33 | 34 | @Test 35 | public void testExistence() { 36 | assertTrue(true); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /tests/ij/UndoTest.java: -------------------------------------------------------------------------------- 1 | package ij; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import org.junit.Test; 6 | 7 | /** 8 | * Unit tests for {@link Undo}. 9 | * 10 | * @author Barry DeZonia 11 | */ 12 | public class UndoTest { 13 | @Test 14 | public void testConstants() { 15 | assertEquals(0,Undo.NOTHING); 16 | assertEquals(1,Undo.FILTER); 17 | assertEquals(2,Undo.TYPE_CONVERSION); 18 | assertEquals(3,Undo.PASTE); 19 | assertEquals(4,Undo.COMPOUND_FILTER); 20 | assertEquals(5,Undo.COMPOUND_FILTER_DONE); 21 | assertEquals(6,Undo.TRANSFORM); 22 | assertEquals(7,Undo.OVERLAY_ADDITION); 23 | } 24 | 25 | // I don't think I can test this 26 | // I can't test internals as it is all private state with no accessors 27 | // I can't test side effects 28 | // it relies on WindowManager to determine which ImagePlus to manipulate 29 | // I somehow need to fake WindowManager into thinking my imagePlus is the one that is active 30 | // but it is tied to threads and windows neither of which I have access to. 31 | } 32 | -------------------------------------------------------------------------------- /tests/ij/gui/FreehandRoiTest.java: -------------------------------------------------------------------------------- 1 | package ij.gui; 2 | 3 | import static org.junit.Assert.assertNotNull; 4 | import ij.IJInfo; 5 | import ij.ImagePlus; 6 | import ij.process.ByteProcessor; 7 | 8 | import org.junit.Test; 9 | 10 | /** 11 | * Unit tests for {@link FreehandRoi}. 12 | * 13 | * @author Barry DeZonia 14 | */ 15 | public class FreehandRoiTest { 16 | 17 | FreehandRoi roi; 18 | 19 | // only one public method - the constructor 20 | @Test 21 | public void testFreehandRoi() { 22 | if (IJInfo.RUN_ENHANCED_TESTS) 23 | { 24 | // the underlying superclass PolygonRoi assumes that an ImageCanvas exists. This next test bombs out as is. 25 | 26 | ImagePlus ip = new ImagePlus("Zoops",new ByteProcessor(2,2,new byte[]{1,2,3,4},null)); 27 | roi = new FreehandRoi(2,4,ip); 28 | assertNotNull(roi); 29 | } 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /tests/ij/gui/ProgressBarTest.java: -------------------------------------------------------------------------------- 1 | package ij.gui; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertNotNull; 5 | 6 | import java.awt.Dimension; 7 | 8 | import org.junit.Test; 9 | 10 | /** 11 | * Unit tests for {@link ProgressBar}. 12 | * 13 | * @author Barry DeZonia 14 | */ 15 | public class ProgressBarTest { 16 | 17 | ProgressBar bar; 18 | 19 | @Test 20 | public void testProgressBar() { 21 | bar = new ProgressBar(100, 20); 22 | assertNotNull(bar); 23 | assertEquals(0,bar.getWidth()); // huh. surprising. 24 | assertEquals(0,bar.getHeight()); // huh. surprising. 25 | } 26 | 27 | @Test 28 | public void testShowDouble() { 29 | bar = new ProgressBar(100, 20); 30 | bar.show(20.0); 31 | // nothing to test - its a visual method 32 | } 33 | 34 | @Test 35 | public void testShowDoubleBoolean() { 36 | bar = new ProgressBar(100, 20); 37 | bar.show(20.0,false); 38 | // nothing to test - its a visual method 39 | bar.show(20.0,true); 40 | // nothing to test - its a visual method 41 | } 42 | 43 | @Test 44 | public void testShowIntInt() { 45 | bar = new ProgressBar(100, 20); 46 | for (int i = 0; i < 5; i++) 47 | bar.show(i,5); 48 | // nothing to test - its a visual method 49 | } 50 | 51 | @Test 52 | public void testUpdateGraphics() { 53 | // can't test - it needs a Graphics context to work 54 | } 55 | 56 | @Test 57 | public void testPaintGraphics() { 58 | // can't test - it needs a Graphics context to work 59 | } 60 | 61 | @Test 62 | public void testGetPreferredSize() { 63 | bar = new ProgressBar(1600, 384); 64 | Dimension size = bar.getPreferredSize(); 65 | assertEquals(1600,size.width); 66 | assertEquals(384,size.height); 67 | } 68 | 69 | @Test 70 | public void testSetBatchMode() { 71 | // no accessor and only visual differences in code - can only test API existence 72 | bar = new ProgressBar(10,3); 73 | bar.setBatchMode(false); 74 | bar.setBatchMode(true); 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /tests/ij/gui/TrimmedButtonTest.java: -------------------------------------------------------------------------------- 1 | package ij.gui; 2 | 3 | import static org.junit.Assert.assertTrue; 4 | 5 | import org.junit.Test; 6 | 7 | /** 8 | * Unit tests for {@link TrimmedButton}. 9 | * 10 | * @author Barry DeZonia 11 | */ 12 | public class TrimmedButtonTest { 13 | 14 | TrimmedButton b; 15 | 16 | /* Tests removed 7-20-10 17 | * because hudson complains about missing gui 18 | 19 | @Test 20 | public void testTrimmedButton() { 21 | b = new TrimmedButton("Hookey Booyah", 4); 22 | Dimension dims = b.getMinimumSize(); 23 | assertEquals(-4,dims.width); 24 | assertEquals(0,dims.height); 25 | } 26 | 27 | @Test 28 | public void testGetMinimumSize() { 29 | b = new TrimmedButton("Hookey Booyah", 1); 30 | Dimension dims = b.getMinimumSize(); 31 | assertEquals(-1,dims.width); 32 | assertEquals(0,dims.height); 33 | } 34 | 35 | @Test 36 | public void testGetPreferredSize() { 37 | b = new TrimmedButton("Hookey Booyah", -2); 38 | Dimension dims = b.getPreferredSize(); 39 | assertEquals(2,dims.width); 40 | assertEquals(0,dims.height); 41 | } 42 | 43 | */ 44 | 45 | // at least one test must be present 46 | @Test 47 | public void testNothing() 48 | { 49 | assertTrue(true); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /tests/ij/io/AbgrFormat.java: -------------------------------------------------------------------------------- 1 | package ij.io; 2 | 3 | /** 4 | * TODO 5 | * 6 | * @author Barry DeZonia 7 | */ 8 | public class AbgrFormat extends PixelFormat { 9 | 10 | AbgrFormat() 11 | { 12 | super("Abgr",4,8,1); // super(String name, int numSamples, int bitsPerSample, int planes) 13 | } 14 | 15 | @Override 16 | boolean canDoImageCombo(int compression, ByteOrder.Value byteOrder, int headerBytes, boolean stripped) 17 | { 18 | // top test replaced commented out test after Wayne's changes to ImageReader in 143.s3 19 | 20 | if (compression != FileInfo.COMPRESSION_NONE) 21 | return false; 22 | 23 | //if (compression == FileInfo.COMPRESSION_UNKNOWN) 24 | // return false; 25 | 26 | if (compression == FileInfo.JPEG) // TODO: remove this restriction to test jpeg compression 27 | return false; 28 | 29 | if (byteOrder == ByteOrder.Value.INTEL) 30 | return false; 31 | 32 | if (stripped && (compression == FileInfo.COMPRESSION_NONE)) 33 | return false; 34 | 35 | return true; 36 | } 37 | 38 | @Override 39 | byte[] nativeBytes(long pix, ByteOrder.Value byteOrder) 40 | { 41 | byte[] output = new byte[4]; 42 | 43 | output[0] = (byte)((pix & 0x000000ff) >> 0); 44 | output[1] = (byte)((pix & 0x0000ff00) >> 8); 45 | output[2] = (byte)((pix & 0x00ff0000) >> 16); 46 | output[3] = (byte)((pix & 0xff000000) >> 24); 47 | 48 | return output; 49 | } 50 | 51 | @Override 52 | byte[] getBytes(long[][] image, int compression, ByteOrder.Value byteOrder, int headerBytes, boolean inStrips, FileInfo fi) 53 | { 54 | initializeFileInfo(fi,FileInfo.ABGR,compression,byteOrder,image.length,image[0].length); 55 | 56 | byte[] output; 57 | 58 | if (inStrips) 59 | output = PixelArranger.arrangeInStrips(this,image,fi); 60 | else 61 | output = PixelArranger.arrangeContiguously(this,image,fi); 62 | 63 | output = PixelArranger.attachHeader(fi,headerBytes,output); 64 | 65 | return output; 66 | 67 | } 68 | 69 | @Override 70 | Object expectedResults(long[][] inputImage) 71 | { 72 | int[] output = new int[inputImage.length * inputImage[0].length]; 73 | 74 | // NOTICE that input is abgr but output is argb 75 | 76 | int i = 0; 77 | for (long[] row : inputImage) 78 | for (long pix : row) 79 | output[i++] = (int)(0xff000000 | (pix & 0xffffff)); 80 | 81 | return output; 82 | } 83 | 84 | @Override 85 | Object pixelsFromBytes(byte[] bytes, ByteOrder.Value order) 86 | { 87 | // this method not tested by ImageWriter. Therefore no implementation until it will be used. 88 | return null; 89 | } 90 | } 91 | 92 | -------------------------------------------------------------------------------- /tests/ij/io/BargFormat.java: -------------------------------------------------------------------------------- 1 | package ij.io; 2 | 3 | /** 4 | * TODO 5 | * 6 | * @author Barry DeZonia 7 | */ 8 | public class BargFormat extends PixelFormat { 9 | 10 | BargFormat() 11 | { 12 | super("Barg",4,8,1); // super(String name, int numSamples, int bitsPerSample, int planes) 13 | } 14 | 15 | @Override 16 | boolean canDoImageCombo(int compression, ByteOrder.Value byteOrder, int headerBytes, boolean stripped) 17 | { 18 | // top test replaced commented out test after Wayne's changes to ImageReader in 143.s3 19 | 20 | if (compression != FileInfo.COMPRESSION_NONE) 21 | return false; 22 | 23 | //if (compression == FileInfo.COMPRESSION_UNKNOWN) 24 | // return false; 25 | 26 | if (compression == FileInfo.COMPRESSION_UNKNOWN) 27 | return false; 28 | if (compression == FileInfo.JPEG) // TODO: remove this restriction to test jpeg compression 29 | return false; 30 | 31 | if (byteOrder == ByteOrder.Value.INTEL) 32 | return false; 33 | 34 | if (stripped && (compression == FileInfo.COMPRESSION_NONE)) 35 | return false; 36 | 37 | return true; 38 | } 39 | 40 | @Override 41 | byte[] nativeBytes(long pix, ByteOrder.Value byteOrder) 42 | { 43 | byte[] output = new byte[4]; 44 | 45 | output[0] = (byte)((pix & 0x000000ff) >> 0); 46 | output[1] = (byte)((pix & 0xff000000) >> 24); 47 | output[2] = (byte)((pix & 0x00ff0000) >> 16); 48 | output[3] = (byte)((pix & 0x0000ff00) >> 8); 49 | 50 | return output; 51 | } 52 | 53 | @Override 54 | byte[] getBytes(long[][] image, int compression, ByteOrder.Value byteOrder, int headerBytes, boolean inStrips, FileInfo fi) 55 | { 56 | initializeFileInfo(fi,FileInfo.BARG,compression,byteOrder,image.length,image[0].length); 57 | 58 | byte[] output; 59 | 60 | if (inStrips) 61 | output = PixelArranger.arrangeInStrips(this,image,fi); 62 | else 63 | output = PixelArranger.arrangeContiguously(this,image,fi); 64 | 65 | output = PixelArranger.attachHeader(fi,headerBytes,output); 66 | 67 | return output; 68 | 69 | } 70 | 71 | @Override 72 | Object expectedResults(long[][] inputImage) 73 | { 74 | int[] output = new int[inputImage.length * inputImage[0].length]; 75 | 76 | // NOTICE that input is barg but output is argb 77 | 78 | int i = 0; 79 | for (long[] row : inputImage) 80 | for (long pix : row) 81 | output[i++] = (int)(0xff000000 | (pix & 0xffffff)); 82 | 83 | return output; 84 | } 85 | 86 | @Override 87 | Object pixelsFromBytes(byte[] bytes, ByteOrder.Value order) 88 | { 89 | // this method not tested by ImageWriter. Therefore no implementation until it will be used. 90 | return null; 91 | } 92 | } 93 | 94 | -------------------------------------------------------------------------------- /tests/ij/io/BgrFormat.java: -------------------------------------------------------------------------------- 1 | package ij.io; 2 | 3 | /** 4 | * TODO 5 | * 6 | * @author Barry DeZonia 7 | */ 8 | public class BgrFormat extends PixelFormat { 9 | 10 | BgrFormat() 11 | { 12 | super("Bgr",3,8,1); // super(String name, int numSamples, int bitsPerSample, int planes) 13 | } 14 | 15 | @Override 16 | boolean canDoImageCombo(int compression, ByteOrder.Value byteOrder, int headerBytes, boolean stripped) 17 | { 18 | if (compression == FileInfo.COMPRESSION_UNKNOWN) 19 | return false; 20 | if (compression == FileInfo.JPEG) // TODO: remove this restriction to test jpeg compression 21 | return false; 22 | 23 | if (byteOrder == ByteOrder.Value.INTEL) 24 | return false; 25 | 26 | if (stripped && (compression == FileInfo.COMPRESSION_NONE)) 27 | return false; 28 | 29 | return true; 30 | } 31 | 32 | @Override 33 | byte[] nativeBytes(long pix, ByteOrder.Value byteOrder) 34 | { 35 | byte[] output = new byte[3]; 36 | 37 | output[0] = (byte)((pix & 0x0000ff) >> 0); 38 | output[1] = (byte)((pix & 0x00ff00) >> 8); 39 | output[2] = (byte)((pix & 0xff0000) >> 16); 40 | 41 | return output; 42 | } 43 | 44 | @Override 45 | byte[] getBytes(long[][] image, int compression, ByteOrder.Value byteOrder, int headerBytes, boolean inStrips, FileInfo fi) 46 | { 47 | initializeFileInfo(fi,FileInfo.BGR,compression,byteOrder,image.length,image[0].length); 48 | 49 | byte[] output; 50 | 51 | if (inStrips) 52 | output = PixelArranger.arrangeInStrips(this,image,fi); 53 | else 54 | output = PixelArranger.arrangeContiguously(this,image,fi); 55 | 56 | output = PixelArranger.attachHeader(fi,headerBytes,output); 57 | 58 | return output; 59 | } 60 | 61 | @Override 62 | Object expectedResults(long[][] inputImage) 63 | { 64 | int[] output = new int[inputImage.length * inputImage[0].length]; 65 | 66 | // NOTICE that input is bgr but output is argb 67 | 68 | int i = 0; 69 | for (long[] row : inputImage) 70 | for (long pix : row) 71 | output[i++] = (int)(0xff000000 | (pix & 0xffffff)); 72 | 73 | return output; 74 | } 75 | 76 | @Override 77 | Object pixelsFromBytes(byte[] bytes, ByteOrder.Value order) 78 | { 79 | // this method not tested by ImageWriter. Therefore no implementation until it will be used. 80 | return null; 81 | } 82 | } 83 | 84 | -------------------------------------------------------------------------------- /tests/ij/io/BitmapFormat.java: -------------------------------------------------------------------------------- 1 | package ij.io; 2 | 3 | /** 4 | * TODO 5 | * 6 | * @author Barry DeZonia 7 | */ 8 | public class BitmapFormat extends PixelFormat { 9 | 10 | BitmapFormat() 11 | { 12 | super("Bitmap",1,1,1); // super(String name, int numSamples, int bitsPerSample, int planes) 13 | } 14 | 15 | @Override 16 | boolean canDoImageCombo(int compression, ByteOrder.Value byteOrder, int headerBytes, boolean stripped) 17 | { 18 | if (compression != FileInfo.COMPRESSION_NONE) 19 | return false; 20 | 21 | if (byteOrder == ByteOrder.Value.INTEL) 22 | return false; 23 | 24 | if (stripped) 25 | return false; 26 | 27 | return true; 28 | } 29 | 30 | @Override 31 | byte[] nativeBytes(long pix, ByteOrder.Value byteOrder) 32 | { 33 | // since this is multiple pixels per byte the basic model does not fit 34 | // getBytes shows how pixels are arranged 35 | 36 | return null; 37 | } 38 | 39 | @Override 40 | byte[] getBytes(long[][] image, int compression, ByteOrder.Value byteOrder, int headerBytes, boolean inStrips, FileInfo fi) 41 | { 42 | initializeFileInfo(fi,FileInfo.BITMAP,compression,byteOrder,image.length,image[0].length); 43 | 44 | int pixPerRow = (int) Math.ceil(fi.width / 8.0); 45 | 46 | byte[] output = new byte[fi.height * pixPerRow]; 47 | 48 | // note that I am only using the lowest 1 bit of the image long for testing purposes 49 | 50 | int i = 0; 51 | byte currByte = 0; 52 | 53 | int rows = fi.height; 54 | int cols = fi.width; 55 | for (int r = 0; r < rows; r++) 56 | for (int c = 0; c < cols; c++) 57 | { 58 | if ((image[r][c] & 1) == 1) // if odd 59 | currByte |= (1 << (7-(c%8))); 60 | if (((c%8) == 7) || (c == (cols-1))) 61 | { 62 | output[i++] = currByte; 63 | currByte = 0; 64 | } 65 | } 66 | 67 | //if (byteOrder == ByteOrder.INTEL) 68 | // ; // nothing to do 69 | 70 | //output = compress(fi,compression,output); 71 | 72 | output = PixelArranger.attachHeader(fi,headerBytes,output); 73 | 74 | return output; 75 | } 76 | 77 | @Override 78 | Object expectedResults(long[][] inputImage) 79 | { 80 | int rows = inputImage.length; 81 | int cols = inputImage[0].length; 82 | 83 | byte[] output = new byte[rows * cols]; 84 | 85 | int i = 0; 86 | for (int r = 0; r < rows; r++) 87 | for (int c = 0; c < cols; c++) 88 | output[i++] = ((inputImage[r][c] & 1) == 1) ? (byte)255 : 0; 89 | 90 | return output; 91 | } 92 | 93 | @Override 94 | Object pixelsFromBytes(byte[] bytes, ByteOrder.Value order) 95 | { 96 | // this method not tested by ImageWriter. Therefore no implementation until it will be used. 97 | return null; 98 | } 99 | } 100 | 101 | -------------------------------------------------------------------------------- /tests/ij/io/ByteOrder.java: -------------------------------------------------------------------------------- 1 | package ij.io; 2 | 3 | /** 4 | * TODO 5 | * 6 | * @author Barry DeZonia 7 | */ 8 | public class ByteOrder { 9 | public enum Value { DEFAULT, INTEL } 10 | } 11 | -------------------------------------------------------------------------------- /tests/ij/io/Color8Format.java: -------------------------------------------------------------------------------- 1 | package ij.io; 2 | 3 | /** 4 | * TODO 5 | * 6 | * @author Barry DeZonia 7 | */ 8 | public class Color8Format extends PixelFormat { 9 | 10 | Color8Format() 11 | { 12 | super("Color8",1,8,1); // super(String name, int numSamples, int bitsPerSample, int planes) 13 | } 14 | 15 | @Override 16 | boolean canDoImageCombo(int compression, ByteOrder.Value byteOrder, int headerBytes, boolean stripped) 17 | { 18 | if (compression == FileInfo.COMPRESSION_UNKNOWN) 19 | return false; 20 | if (compression == FileInfo.JPEG) 21 | return false; 22 | 23 | if (byteOrder == ByteOrder.Value.INTEL) 24 | return false; 25 | 26 | if (stripped && (compression == FileInfo.COMPRESSION_NONE)) 27 | return false; 28 | 29 | return true; 30 | } 31 | 32 | @Override 33 | byte[] nativeBytes(long pix, ByteOrder.Value byteOrder) 34 | { 35 | return new byte[] {(byte)(pix & 0xff)}; 36 | } 37 | 38 | @Override 39 | byte[] getBytes(long[][] image, int compression, ByteOrder.Value byteOrder, int headerBytes, boolean inStrips, FileInfo fi) 40 | { 41 | initializeFileInfo(fi,FileInfo.COLOR8,compression,byteOrder,image.length,image[0].length); 42 | 43 | byte[] output; 44 | 45 | if (inStrips) 46 | output = PixelArranger.arrangeInStrips(this,image,fi); 47 | else 48 | output = PixelArranger.arrangeContiguously(this,image,fi); 49 | 50 | output = PixelArranger.attachHeader(fi,headerBytes,output); 51 | 52 | return output; 53 | } 54 | 55 | @Override 56 | Object expectedResults(long[][] inputImage) 57 | { 58 | byte[] output = new byte[inputImage.length * inputImage[0].length]; 59 | 60 | int i = 0; 61 | for (long[] row : inputImage) 62 | for (long pix : row) 63 | output[i++] = (byte) (pix & 0xff); 64 | 65 | return output; 66 | } 67 | 68 | @Override 69 | Object pixelsFromBytes(byte[] bytes, ByteOrder.Value order) 70 | { 71 | return bytes; 72 | } 73 | } 74 | 75 | -------------------------------------------------------------------------------- /tests/ij/io/DirectoryChooserTest.java: -------------------------------------------------------------------------------- 1 | package ij.io; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import ij.IJInfo; 5 | 6 | import org.junit.Test; 7 | 8 | /** 9 | * Unit tests for {@link DirectoryChooser}. 10 | * 11 | * @author Barry DeZonia 12 | */ 13 | public class DirectoryChooserTest { 14 | 15 | @Test 16 | public void testDirectoryChooser() { 17 | if (IJInfo.RUN_GUI_TESTS) { 18 | DirectoryChooser chooser = new DirectoryChooser("Choose any path"); 19 | assertEquals(true,true); 20 | } 21 | } 22 | 23 | // this test is not done in a OS agnostic fashion!!! must fix 24 | // do these tests need to go away? Or do we need to make mock calls to choose a directory? 25 | @Test 26 | public void testGetDirectory() { 27 | if (IJInfo.RUN_GUI_TESTS) { 28 | DirectoryChooser chooser = new DirectoryChooser("Choose path called /System/"); 29 | assertEquals("/System/", chooser.getDirectory()); 30 | } 31 | } 32 | 33 | @Test 34 | public void testSetDefaultDirectory() { 35 | if (IJInfo.RUN_GUI_TESTS) { 36 | DirectoryChooser.setDefaultDirectory("/Library/"); 37 | DirectoryChooser chooser = new DirectoryChooser("See that path == /Library/"); 38 | assertEquals(true,true); 39 | } 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /tests/ij/io/Gray12UnsignedFormat.java: -------------------------------------------------------------------------------- 1 | package ij.io; 2 | 3 | /** 4 | * TODO 5 | * 6 | * @author Barry DeZonia 7 | */ 8 | public class Gray12UnsignedFormat extends PixelFormat { 9 | 10 | Gray12UnsignedFormat() 11 | { 12 | super("Gray12Unsigned",1,12,1); // super(String name, int numSamples, int bitsPerSample, int planes) 13 | } 14 | 15 | @Override 16 | boolean canDoImageCombo(int compression, ByteOrder.Value byteOrder, int headerBytes, boolean stripped) 17 | { 18 | if (compression != FileInfo.COMPRESSION_NONE) 19 | return false; 20 | 21 | if (byteOrder == ByteOrder.Value.INTEL) 22 | return false; 23 | 24 | if (stripped) 25 | return false; 26 | 27 | return true; 28 | } 29 | 30 | @Override 31 | byte[] nativeBytes(long pix, ByteOrder.Value byteOrder) 32 | { 33 | // since this format spans byte boundaries it cannot work with the basic model 34 | // see twelveBitEncoder() for an idea how the pixels are arranged 35 | 36 | return null; 37 | } 38 | 39 | @Override 40 | byte[] getBytes(long[][] image, int compression, ByteOrder.Value byteOrder, int headerBytes, boolean inStrips, FileInfo fi) 41 | { 42 | initializeFileInfo(fi,FileInfo.GRAY12_UNSIGNED,compression,byteOrder,image.length,image[0].length); 43 | 44 | byte[] output = TwelveBitEncoder.encode(image); 45 | 46 | // if (byteOrder == ByteOrder.INTEL) 47 | // ; // nothing to do 48 | 49 | output = PixelArranger.attachHeader(fi,headerBytes,output); 50 | 51 | return output; 52 | } 53 | 54 | @Override 55 | Object expectedResults(long[][] inputImage) 56 | { 57 | short[] output = new short[inputImage.length * inputImage[0].length]; 58 | 59 | int i = 0; 60 | for (long[] row : inputImage) 61 | for (long pix: row) 62 | output[i++] = (short)(pix & 0xfff); 63 | 64 | return output; 65 | } 66 | 67 | @Override 68 | Object pixelsFromBytes(byte[] bytes, ByteOrder.Value order) 69 | { 70 | // this method not tested by ImageWriter. Therefore no implementation until it will be used. 71 | return null; 72 | } 73 | } 74 | 75 | -------------------------------------------------------------------------------- /tests/ij/io/Gray16SignedFormat.java: -------------------------------------------------------------------------------- 1 | package ij.io; 2 | 3 | /** 4 | * TODO 5 | * 6 | * @author Barry DeZonia 7 | */ 8 | public class Gray16SignedFormat extends PixelFormat { 9 | 10 | Gray16SignedFormat() 11 | { 12 | super("Gray16Signed",1,16,1); // super(String name, int numSamples, int bitsPerSample, int planes) 13 | } 14 | 15 | @Override 16 | boolean canDoImageCombo(int compression, ByteOrder.Value byteOrder, int headerBytes, boolean stripped) 17 | { 18 | if (compression == FileInfo.COMPRESSION_UNKNOWN) 19 | return false; 20 | if (compression == FileInfo.JPEG) 21 | return false; 22 | // BDZ - removed to reflect code as of 1.43s7 23 | //if (compression == FileInfo.PACK_BITS) 24 | // return false; 25 | 26 | // BDZ - removed to reflect code as of 1.43s7 27 | //if (stripped && (compression == FileInfo.COMPRESSION_NONE)) 28 | // return false; 29 | 30 | return true; 31 | } 32 | 33 | @Override 34 | byte[] nativeBytes(long pix, ByteOrder.Value byteOrder) 35 | { 36 | byte[] output = new byte[2]; 37 | 38 | output[0] = (byte)((pix & 0xff00) >> 8); 39 | output[1] = (byte)((pix & 0x00ff) >> 0); 40 | 41 | if (byteOrder == ByteOrder.Value.INTEL) 42 | PixelArranger.reverse(output); 43 | 44 | return output; 45 | } 46 | 47 | @Override 48 | byte[] getBytes(long[][] image, int compression, ByteOrder.Value byteOrder, int headerBytes, boolean inStrips, FileInfo fi) 49 | { 50 | initializeFileInfo(fi,FileInfo.GRAY16_SIGNED,compression,byteOrder,image.length,image[0].length); 51 | 52 | byte[] output; 53 | 54 | if (inStrips) 55 | output = PixelArranger.arrangeInStrips(this,image,fi); 56 | else 57 | output = PixelArranger.arrangeContiguously(this,image,fi); 58 | 59 | output = PixelArranger.attachHeader(fi,headerBytes,output); 60 | 61 | return output; 62 | } 63 | 64 | @Override 65 | Object expectedResults(long[][] inputImage) 66 | { 67 | short[] output = new short[inputImage.length * inputImage[0].length]; 68 | 69 | int i = 0; 70 | for (long[] row : inputImage) 71 | for (long pix : row) 72 | output[i++] = (short) (32768 + (pix & 0xffff)); // bias taken from ImageReader.readPixels() 73 | return output; 74 | } 75 | 76 | @Override 77 | Object pixelsFromBytes(byte[] bytes, ByteOrder.Value order) 78 | { 79 | int numShorts = bytes.length / 2; 80 | short[] output = new short[numShorts]; 81 | 82 | for (int i = 0; i < numShorts; i++) 83 | { 84 | //TODO figure out why biasing not needed here 85 | if (order == ByteOrder.Value.INTEL) 86 | output[i] = (short)(((bytes[2*i+1] & 0xff) << 8) | (bytes[2*i] & 0xff)); 87 | else 88 | output[i] = (short)(((bytes[2*i] & 0xff) << 8) | (bytes[2*i+1] & 0xff)); 89 | } 90 | return output; 91 | } 92 | } 93 | 94 | -------------------------------------------------------------------------------- /tests/ij/io/Gray16UnsignedFormat.java: -------------------------------------------------------------------------------- 1 | package ij.io; 2 | 3 | /** 4 | * TODO 5 | * 6 | * @author Barry DeZonia 7 | */ 8 | public class Gray16UnsignedFormat extends PixelFormat { 9 | 10 | Gray16UnsignedFormat() 11 | { 12 | super("Gray16Unsigned",1,16,1); // super(String name, int numSamples, int bitsPerSample, int planes) 13 | } 14 | 15 | @Override 16 | boolean canDoImageCombo(int compression, ByteOrder.Value byteOrder, int headerBytes, boolean stripped) 17 | { 18 | if (compression == FileInfo.COMPRESSION_UNKNOWN) 19 | return false; 20 | if (compression == FileInfo.JPEG) 21 | return false; 22 | // BDZ - removed to reflect code as of 1.43s7 23 | //if (compression == FileInfo.PACK_BITS) 24 | // return false; 25 | 26 | // BDZ - removed to reflect code as of 1.43s7 27 | //if (stripped && (compression == FileInfo.COMPRESSION_NONE)) 28 | // return false; 29 | 30 | return true; 31 | } 32 | 33 | @Override 34 | byte[] nativeBytes(long pix, ByteOrder.Value byteOrder) 35 | { 36 | byte[] output = new byte[2]; 37 | 38 | output[0] = (byte)((pix & 0xff00) >> 8); 39 | output[1] = (byte)((pix & 0x00ff) >> 0); 40 | 41 | if (byteOrder == ByteOrder.Value.INTEL) 42 | PixelArranger.reverse(output); 43 | 44 | return output; 45 | } 46 | 47 | @Override 48 | byte[] getBytes(long[][] image, int compression, ByteOrder.Value byteOrder, int headerBytes, boolean inStrips, FileInfo fi) 49 | { 50 | initializeFileInfo(fi,FileInfo.GRAY16_UNSIGNED,compression,byteOrder,image.length,image[0].length); 51 | 52 | byte[] output; 53 | 54 | if (inStrips) 55 | output = PixelArranger.arrangeInStrips(this,image,fi); 56 | else 57 | output = PixelArranger.arrangeContiguously(this,image,fi); 58 | 59 | output = PixelArranger.attachHeader(fi,headerBytes,output); 60 | 61 | return output; 62 | } 63 | 64 | @Override 65 | Object expectedResults(long[][] inputImage) 66 | { 67 | short[] output = new short[inputImage.length * inputImage[0].length]; 68 | 69 | int i = 0; 70 | for (long[] row : inputImage) 71 | for (long pix : row) 72 | output[i++] = (short)(pix & 0xffff); 73 | return output; 74 | } 75 | 76 | @Override 77 | Object pixelsFromBytes(byte[] bytes, ByteOrder.Value order) 78 | { 79 | int numShorts = bytes.length / 2; 80 | short[] output = new short[numShorts]; 81 | 82 | for (int i = 0; i < numShorts; i++) 83 | { 84 | if (order == ByteOrder.Value.INTEL) 85 | output[i] = (short)(((bytes[2*i+1] & 0xff) << 8) | (bytes[2*i] & 0xff)); 86 | else 87 | output[i] = (short)(((bytes[2*i] & 0xff) << 8) | (bytes[2*i+1] & 0xff)); 88 | } 89 | return output; 90 | } 91 | } 92 | 93 | -------------------------------------------------------------------------------- /tests/ij/io/Gray24UnsignedFormat.java: -------------------------------------------------------------------------------- 1 | package ij.io; 2 | 3 | /** 4 | * TODO 5 | * 6 | * @author Barry DeZonia 7 | */ 8 | public class Gray24UnsignedFormat extends PixelFormat { 9 | 10 | Gray24UnsignedFormat() 11 | { 12 | super("Gray24Unsigned",1,24,1); // super(String name, int numSamples, int bitsPerSample, int planes) 13 | } 14 | 15 | @Override 16 | boolean canDoImageCombo(int compression, ByteOrder.Value byteOrder, int headerBytes, boolean stripped) 17 | { 18 | if (compression != FileInfo.COMPRESSION_NONE) 19 | return false; 20 | 21 | if (byteOrder == ByteOrder.Value.INTEL) 22 | return false; 23 | 24 | if (stripped) 25 | return false; 26 | 27 | return true; 28 | } 29 | 30 | @Override 31 | byte[] nativeBytes(long pix, ByteOrder.Value byteOrder) 32 | { 33 | byte[] output = new byte[3]; 34 | 35 | output[0] = (byte) ((pix & 0x0000ff) >> 0); 36 | output[1] = (byte) ((pix & 0x00ff00) >> 8); 37 | output[2] = (byte) ((pix & 0xff0000) >> 16); 38 | 39 | return output; 40 | } 41 | 42 | @Override 43 | byte[] getBytes(long[][] image, int compression, ByteOrder.Value byteOrder, int headerBytes, boolean inStrips, FileInfo fi) 44 | { 45 | initializeFileInfo(fi,FileInfo.GRAY24_UNSIGNED,compression,byteOrder,image.length,image[0].length); 46 | 47 | byte[] output; 48 | 49 | // ALWAYS arrange contiguously in this case 50 | output = PixelArranger.arrangeContiguously(this,image,fi); 51 | 52 | output = PixelArranger.attachHeader(fi,headerBytes,output); 53 | 54 | return output; 55 | } 56 | 57 | @Override 58 | Object expectedResults(long[][] inputImage) 59 | { 60 | float[] output = new float[inputImage.length * inputImage[0].length]; 61 | 62 | int i = 0; 63 | for (long[] row : inputImage) 64 | for (long pix: row) 65 | output[i++] = (pix & 0xffffff); 66 | 67 | return output; 68 | } 69 | 70 | @Override 71 | Object pixelsFromBytes(byte[] bytes, ByteOrder.Value order) 72 | { 73 | // this method not tested by ImageWriter. Therefore no implementation until it will be used. 74 | return null; 75 | } 76 | } 77 | 78 | -------------------------------------------------------------------------------- /tests/ij/io/Gray32FloatFormat.java: -------------------------------------------------------------------------------- 1 | package ij.io; 2 | 3 | /** 4 | * TODO 5 | * 6 | * @author Barry DeZonia 7 | */ 8 | public class Gray32FloatFormat extends PixelFormat { 9 | 10 | Gray32FloatFormat() 11 | { 12 | super("Gray32Float",1,32,1); // super(String name, int numSamples, int bitsPerSample, int planes) 13 | } 14 | 15 | @Override 16 | boolean canDoImageCombo(int compression, ByteOrder.Value byteOrder, int headerBytes, boolean stripped) 17 | { 18 | if (compression != FileInfo.COMPRESSION_NONE) 19 | return false; 20 | 21 | if (stripped) 22 | return false; 23 | 24 | return true; 25 | } 26 | 27 | @Override 28 | byte[] nativeBytes(long pix, ByteOrder.Value byteOrder) 29 | { 30 | byte[] output = new byte[4]; 31 | 32 | float fPix = pix; 33 | 34 | int bPix = Float.floatToIntBits(fPix); 35 | 36 | output[0] = (byte)((bPix & 0xff000000) >> 24); 37 | output[1] = (byte)((bPix & 0x00ff0000) >> 16); 38 | output[2] = (byte)((bPix & 0x0000ff00) >> 8); 39 | output[3] = (byte)((bPix & 0x000000ff) >> 0); 40 | 41 | if (byteOrder == ByteOrder.Value.INTEL) 42 | PixelArranger.reverse(output); 43 | 44 | return output; 45 | } 46 | 47 | @Override 48 | byte[] getBytes(long[][] image, int compression, ByteOrder.Value byteOrder, int headerBytes, boolean inStrips, FileInfo fi) 49 | { 50 | initializeFileInfo(fi,FileInfo.GRAY32_FLOAT,compression,byteOrder,image.length,image[0].length); 51 | 52 | byte[] output; 53 | 54 | // ALWAYS contiguous in this case 55 | output = PixelArranger.arrangeContiguously(this,image,fi); 56 | 57 | output = PixelArranger.attachHeader(fi,headerBytes,output); 58 | 59 | return output; 60 | } 61 | 62 | @Override 63 | Object expectedResults(long[][] inputImage) 64 | { 65 | float[] output = new float[inputImage.length * inputImage[0].length]; 66 | 67 | int i = 0; 68 | for (long[] row : inputImage) 69 | for (long pix : row) 70 | output[i++] = pix; 71 | return output; 72 | } 73 | 74 | @Override 75 | Object pixelsFromBytes(byte[] bytes, ByteOrder.Value order) 76 | { 77 | int numFloats = bytes.length / 4; 78 | float[] output = new float[numFloats]; 79 | for (int i = 0; i < numFloats; i++) 80 | { 81 | int theInt; 82 | 83 | if (order == ByteOrder.Value.INTEL) 84 | theInt = ((bytes[4*i+3] & 0xff) << 24) | ((bytes[4*i+2] & 0xff) << 16) | ((bytes[4*i+1] & 0xff) << 8) | ((bytes[4*i+0] & 0xff) << 0); 85 | else 86 | theInt = ((bytes[4*i+0] & 0xff) << 24) | ((bytes[4*i+1] & 0xff) << 16) | ((bytes[4*i+2] & 0xff) << 8) | ((bytes[4*i+3] & 0xff) << 0); 87 | output[i] = Float.intBitsToFloat(theInt); 88 | } 89 | return output; 90 | } 91 | } 92 | 93 | -------------------------------------------------------------------------------- /tests/ij/io/Gray32IntFormat.java: -------------------------------------------------------------------------------- 1 | package ij.io; 2 | 3 | /** 4 | * TODO 5 | * 6 | * @author Barry DeZonia 7 | */ 8 | public class Gray32IntFormat extends PixelFormat { 9 | 10 | Gray32IntFormat() 11 | { 12 | super("Gray32Int",1,32,1); // super(String name, int numSamples, int bitsPerSample, int planes) 13 | } 14 | 15 | @Override 16 | boolean canDoImageCombo(int compression, ByteOrder.Value byteOrder, int headerBytes, boolean stripped) 17 | { 18 | if (compression != FileInfo.COMPRESSION_NONE) 19 | return false; 20 | 21 | if (stripped) 22 | return false; 23 | 24 | return true; 25 | } 26 | 27 | @Override 28 | byte[] nativeBytes(long pix, ByteOrder.Value byteOrder) 29 | { 30 | byte[] output = new byte[4]; 31 | 32 | output[0] = (byte)((pix & 0xff000000) >> 24); 33 | output[1] = (byte)((pix & 0x00ff0000) >> 16); 34 | output[2] = (byte)((pix & 0x0000ff00) >> 8); 35 | output[3] = (byte)((pix & 0x000000ff) >> 0); 36 | 37 | if (byteOrder == ByteOrder.Value.INTEL) 38 | PixelArranger.reverse(output); 39 | 40 | return output; 41 | } 42 | 43 | @Override 44 | byte[] getBytes(long[][] image, int compression, ByteOrder.Value byteOrder, int headerBytes, boolean inStrips, FileInfo fi) 45 | { 46 | initializeFileInfo(fi,FileInfo.GRAY32_INT,compression,byteOrder,image.length,image[0].length); 47 | 48 | byte[] output; 49 | 50 | if (inStrips) 51 | output = PixelArranger.arrangeInStrips(this,image,fi); 52 | else 53 | output = PixelArranger.arrangeContiguously(this,image,fi); 54 | 55 | output = PixelArranger.attachHeader(fi,headerBytes,output); 56 | 57 | return output; 58 | } 59 | 60 | @Override 61 | Object expectedResults(long[][] inputImage) 62 | { 63 | float[] output = new float[inputImage.length * inputImage[0].length]; 64 | 65 | int i = 0; 66 | for (long[] row : inputImage) 67 | for (long pix : row) 68 | output[i++] = (int)(pix & 0xffffffffL); 69 | return output; 70 | } 71 | 72 | @Override 73 | Object pixelsFromBytes(byte[] bytes, ByteOrder.Value order) 74 | { 75 | // this method not tested by ImageWriter. Therefore no implementation until it will be used. 76 | return null; 77 | } 78 | } 79 | 80 | -------------------------------------------------------------------------------- /tests/ij/io/Gray32UnsignedFormat.java: -------------------------------------------------------------------------------- 1 | package ij.io; 2 | 3 | /** 4 | * TODO 5 | * 6 | * @author Barry DeZonia 7 | */ 8 | public class Gray32UnsignedFormat extends PixelFormat { 9 | 10 | Gray32UnsignedFormat() 11 | { 12 | super("Gray32Unsigned",1,32,1); // super(String name, int numSamples, int bitsPerSample, int planes) 13 | } 14 | 15 | @Override 16 | boolean canDoImageCombo(int compression, ByteOrder.Value byteOrder, int headerBytes, boolean stripped) 17 | { 18 | if (compression != FileInfo.COMPRESSION_NONE) 19 | return false; 20 | 21 | if (stripped) 22 | return false; 23 | 24 | return true; 25 | } 26 | 27 | @Override 28 | byte[] nativeBytes(long pix, ByteOrder.Value byteOrder) 29 | { 30 | byte[] output = new byte[4]; 31 | 32 | output[0] = (byte)((pix & 0xff000000) >> 24); 33 | output[1] = (byte)((pix & 0x00ff0000) >> 16); 34 | output[2] = (byte)((pix & 0x0000ff00) >> 8); 35 | output[3] = (byte)((pix & 0x000000ff) >> 0); 36 | 37 | if (byteOrder == ByteOrder.Value.INTEL) 38 | PixelArranger.reverse(output); 39 | 40 | return output; 41 | } 42 | 43 | @Override 44 | byte[] getBytes(long[][] image, int compression, ByteOrder.Value byteOrder, int headerBytes, boolean inStrips, FileInfo fi) 45 | { 46 | initializeFileInfo(fi,FileInfo.GRAY32_UNSIGNED,compression,byteOrder,image.length,image[0].length); 47 | 48 | byte[] output; 49 | 50 | if (inStrips) 51 | output = PixelArranger.arrangeInStrips(this,image,fi); 52 | else 53 | output = PixelArranger.arrangeContiguously(this,image,fi); 54 | 55 | output = PixelArranger.attachHeader(fi,headerBytes,output); 56 | 57 | return output; 58 | } 59 | 60 | @Override 61 | Object expectedResults(long[][] inputImage) 62 | { 63 | float[] output = new float[inputImage.length * inputImage[0].length]; 64 | 65 | int i = 0; 66 | for (long[] row : inputImage) 67 | for (long pix : row) 68 | output[i++] = (pix & 0xffffffffL); 69 | return output; 70 | } 71 | 72 | @Override 73 | Object pixelsFromBytes(byte[] bytes, ByteOrder.Value order) 74 | { 75 | // this method not tested by ImageWriter. Therefore no implementation until it will be used. 76 | return null; 77 | } 78 | } 79 | 80 | -------------------------------------------------------------------------------- /tests/ij/io/Gray64FloatFormat.java: -------------------------------------------------------------------------------- 1 | package ij.io; 2 | 3 | /** 4 | * TODO 5 | * 6 | * @author Barry DeZonia 7 | */ 8 | public class Gray64FloatFormat extends PixelFormat { 9 | 10 | Gray64FloatFormat() 11 | { 12 | super("Gray64Float",1,64,1); // super(String name, int numSamples, int bitsPerSample, int planes) 13 | } 14 | 15 | @Override 16 | boolean canDoImageCombo(int compression, ByteOrder.Value byteOrder, int headerBytes, boolean stripped) 17 | { 18 | if (compression != FileInfo.COMPRESSION_NONE) 19 | return false; 20 | 21 | if (stripped) 22 | return false; 23 | 24 | return true; 25 | } 26 | 27 | @Override 28 | byte[] nativeBytes(long pix, ByteOrder.Value byteOrder) 29 | { 30 | byte[] output = new byte[8]; 31 | 32 | double dPix = pix; 33 | 34 | long bPix = Double.doubleToLongBits(dPix); 35 | 36 | output[0] = (byte)((bPix & 0xff00000000000000L) >> 56); 37 | output[1] = (byte)((bPix & 0x00ff000000000000L) >> 48); 38 | output[2] = (byte)((bPix & 0x0000ff0000000000L) >> 40); 39 | output[3] = (byte)((bPix & 0x000000ff00000000L) >> 32); 40 | output[4] = (byte)((bPix & 0x00000000ff000000L) >> 24); 41 | output[5] = (byte)((bPix & 0x0000000000ff0000L) >> 16); 42 | output[6] = (byte)((bPix & 0x000000000000ff00L) >> 8); 43 | output[7] = (byte)((bPix & 0x00000000000000ffL) >> 0); 44 | 45 | if (byteOrder == ByteOrder.Value.INTEL) 46 | PixelArranger.reverse(output); 47 | 48 | return output; 49 | } 50 | 51 | @Override 52 | byte[] getBytes(long[][] image, int compression, ByteOrder.Value byteOrder, int headerBytes, boolean inStrips, FileInfo fi) 53 | { 54 | initializeFileInfo(fi,FileInfo.GRAY64_FLOAT,compression,byteOrder,image.length,image[0].length); 55 | 56 | 57 | byte[] output; 58 | 59 | // ALWAYS contiguous in this case 60 | output = PixelArranger.arrangeContiguously(this,image,fi); 61 | 62 | output = PixelArranger.attachHeader(fi,headerBytes,output); 63 | 64 | return output; 65 | 66 | } 67 | 68 | @Override 69 | Object expectedResults(long[][] inputImage) 70 | { 71 | float[] output = new float[inputImage.length * inputImage[0].length]; 72 | 73 | int i = 0; 74 | for (long[] row : inputImage) 75 | for (long pix : row) 76 | output[i++] = pix; 77 | return output; 78 | } 79 | 80 | @Override 81 | Object pixelsFromBytes(byte[] bytes, ByteOrder.Value order) 82 | { 83 | // this method not tested by ImageWriter. Therefore no implementation until it will be used. 84 | return null; 85 | } 86 | } 87 | 88 | -------------------------------------------------------------------------------- /tests/ij/io/Gray8Format.java: -------------------------------------------------------------------------------- 1 | package ij.io; 2 | 3 | /** 4 | * TODO 5 | * 6 | * @author Barry DeZonia 7 | */ 8 | public class Gray8Format extends PixelFormat { 9 | 10 | Gray8Format() 11 | { 12 | super("Gray8",1,8,1); // super(String name, int numSamples, int bitsPerSample, int planes) 13 | } 14 | 15 | @Override 16 | boolean canDoImageCombo(int compression, ByteOrder.Value byteOrder, int headerBytes, boolean stripped) 17 | { 18 | if (compression == FileInfo.COMPRESSION_UNKNOWN) 19 | return false; 20 | if (compression == FileInfo.JPEG) 21 | return false; 22 | 23 | if (byteOrder == ByteOrder.Value.INTEL) 24 | return false; 25 | 26 | if (stripped && (compression == FileInfo.COMPRESSION_NONE)) 27 | return false; 28 | 29 | return true; 30 | } 31 | 32 | @Override 33 | byte[] nativeBytes(long pix, ByteOrder.Value byteOrder) 34 | { 35 | return new byte[] {(byte)(pix & 0xff)}; 36 | } 37 | 38 | @Override 39 | byte[] getBytes(long[][] image, int compression, ByteOrder.Value byteOrder, int headerBytes, boolean inStrips, FileInfo fi) 40 | { 41 | initializeFileInfo(fi,FileInfo.GRAY8,compression,byteOrder,image.length,image[0].length); 42 | 43 | byte[] output; 44 | 45 | if (inStrips) 46 | output = PixelArranger.arrangeInStrips(this,image,fi); 47 | else 48 | output = PixelArranger.arrangeContiguously(this,image,fi); 49 | 50 | output = PixelArranger.attachHeader(fi,headerBytes,output); 51 | 52 | return output; 53 | } 54 | 55 | @Override 56 | Object expectedResults(long[][] inputImage) 57 | { 58 | byte[] output = new byte[inputImage.length * inputImage[0].length]; 59 | 60 | int i = 0; 61 | for (long[] row : inputImage) 62 | for (long pix : row) 63 | output[i++] = (byte) (pix & 0xff); 64 | 65 | return output; 66 | } 67 | 68 | @Override 69 | Object pixelsFromBytes(byte[] bytes, ByteOrder.Value order) 70 | { 71 | return bytes; 72 | } 73 | } 74 | 75 | -------------------------------------------------------------------------------- /tests/ij/io/JpegEncoder.java: -------------------------------------------------------------------------------- 1 | package ij.io; 2 | 3 | import loci.formats.codec.CodecOptions; 4 | import loci.formats.codec.JPEGCodec; 5 | 6 | /** 7 | * TODO 8 | * 9 | * @author Barry DeZonia 10 | */ 11 | public class JpegEncoder { 12 | 13 | JpegEncoder() {} 14 | 15 | static public byte[] encode(byte[] input, PixelFormat format, FileInfo fi) 16 | { 17 | byte[] output = null; 18 | try { 19 | CodecOptions codecOptions = new CodecOptions(); 20 | codecOptions.height = fi.height; 21 | codecOptions.width = fi.width; 22 | codecOptions.channels = format.numSamples(); 23 | codecOptions.bitsPerSample = format.bitsPerSample(); 24 | codecOptions.interleaved = (format.planes() == 1); 25 | codecOptions.littleEndian = fi.intelByteOrder; 26 | //codecOptions.signed = (format == gray16SignedFormat); 27 | codecOptions.signed = false; 28 | output = new JPEGCodec().compress(input, codecOptions); 29 | } catch (Exception e) { 30 | e.printStackTrace(); 31 | } 32 | return output; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /tests/ij/io/LzwDiffEncoder.java: -------------------------------------------------------------------------------- 1 | package ij.io; 2 | 3 | /** 4 | * TODO 5 | * 6 | * @author Barry DeZonia 7 | */ 8 | public class LzwDiffEncoder { 9 | 10 | LzwDiffEncoder() {} 11 | 12 | // unfortunately this method needed to be tweaked outside the overall design to accommodate intel byte orders for 16 bit 13 | // sample depths. We could eliminate the extra code at the expense of redesigning some of the other classes. 14 | 15 | static private byte[] differentiate(byte[] input, PixelFormat format, FileInfo fi) 16 | { 17 | int offset = format.numSamples(); 18 | 19 | // multiplane data is stored contiguously a plane at a time : offset to neighbor byte 20 | if (format.planes() > 1) 21 | offset = 1; 22 | 23 | byte[] data = input.clone(); 24 | 25 | // if 16 bit samples must calc differences on original pixel data and not bytes 26 | if (format.bitsPerSample() == 16) 27 | { 28 | int actualPix = data.length / 2; 29 | 30 | for (int b = actualPix-1; b >= 0; b--) 31 | { 32 | if (b / offset % fi.width == 0) 33 | continue; 34 | 35 | int currPix, prevPix; 36 | 37 | if (fi.intelByteOrder) 38 | { 39 | currPix = ((data[b*2+0] & 0xff) << 0) | ((data[b*2+1] & 0xff) << 8); 40 | prevPix = ((data[b*2-2] & 0xff) << 0) | ((data[b*2-1] & 0xff) << 8); 41 | currPix -= prevPix; 42 | data[b*2+0] = (byte)((currPix & 0x00ff) >> 0); 43 | data[b*2+1] = (byte)((currPix & 0xff00) >> 8); 44 | } 45 | else 46 | { 47 | currPix = ((data[b*2+0] & 0xff) << 8) | ((data[b*2+1] & 0xff) << 0); 48 | prevPix = ((data[b*2-2] & 0xff) << 8) | ((data[b*2-1] & 0xff) << 0); 49 | currPix -= prevPix; 50 | data[b*2+0] = (byte)((currPix & 0xff00) >> 8); 51 | data[b*2+1] = (byte)((currPix & 0x00ff) >> 0); 52 | } 53 | } 54 | 55 | } 56 | else // input data is of type byte and we can calc differences as is 57 | for (int b=data.length-1; b>=0; b--) 58 | { 59 | // this code adapted from TiffCompression code in BioFormats 60 | if (b / offset % fi.width == 0) 61 | continue; 62 | data[b] -= data[b - offset]; 63 | } 64 | 65 | return data; 66 | } 67 | 68 | static public byte[] encode(byte[] input, PixelFormat format, FileInfo fi) 69 | { 70 | byte[] adjustedInput = differentiate(input, format, fi); 71 | 72 | byte[] output = LzwEncoder.encode(adjustedInput); 73 | 74 | return output; 75 | } 76 | } 77 | 78 | -------------------------------------------------------------------------------- /tests/ij/io/LzwEncoder.java: -------------------------------------------------------------------------------- 1 | package ij.io; 2 | 3 | import loci.formats.codec.CodecOptions; 4 | import loci.formats.codec.LZWCodec; 5 | 6 | /** 7 | * TODO 8 | * 9 | * @author Barry DeZonia 10 | */ 11 | public class LzwEncoder { 12 | 13 | LzwEncoder() {} 14 | 15 | static public byte[] encode(byte[] input) 16 | { 17 | byte[] output = null; 18 | try { 19 | output = new LZWCodec().compress(input, CodecOptions.getDefaultOptions()); // compress the output data 20 | } catch (Exception e) 21 | { 22 | e.printStackTrace(); 23 | } 24 | return output; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /tests/ij/io/PackbitsEncoderNaive.java: -------------------------------------------------------------------------------- 1 | package ij.io; 2 | 3 | // PackbitsEncoderNaive is designed with two things in mind 4 | // - test ImageReader's ability to handle more than one style of packbits encoded data 5 | // - stand in for the real PackBitsEncoder if we think it is ever faulty 6 | 7 | /** 8 | * TODO 9 | * 10 | * @author Barry DeZonia 11 | */ 12 | public class PackbitsEncoderNaive { 13 | 14 | PackbitsEncoderNaive() {} 15 | 16 | static public byte[] encode(byte[] input) 17 | { 18 | byte[] output = new byte[input.length*2]; 19 | int i = 0; 20 | for (byte b : input) 21 | { 22 | output[i++] = 0; 23 | output[i++] = b; 24 | } 25 | return output; 26 | } 27 | } 28 | 29 | -------------------------------------------------------------------------------- /tests/ij/io/PixelFormat.java: -------------------------------------------------------------------------------- 1 | package ij.io; 2 | 3 | /** 4 | * TODO 5 | * 6 | * @author Barry DeZonia 7 | */ 8 | public abstract class PixelFormat { 9 | 10 | private String name; // might be useful for debugging purposes. otherwise could be an interface 11 | private int numSamples; 12 | private int bitsPerSample; 13 | private int planes; 14 | 15 | public int numSamples() { return numSamples; } 16 | public int bitsPerSample() { return bitsPerSample; } 17 | public int planes() { return planes; } 18 | public String name() { return name; } 19 | 20 | 21 | abstract boolean canDoImageCombo(int compression, ByteOrder.Value byteOrder, int headerBytes, boolean stripped); 22 | abstract byte[] nativeBytes(long pixel, ByteOrder.Value byteOrder); 23 | abstract byte[] getBytes(long[][] image, int compression, ByteOrder.Value byteOrder, int headerBytes, boolean inStrips, FileInfo fi); 24 | abstract Object expectedResults(long[][] inputImage); 25 | abstract Object pixelsFromBytes(byte[] bytes, ByteOrder.Value byteOrder); 26 | 27 | PixelFormat(String name, int numSamples, int bitsPerSample, int planes) 28 | { 29 | this.name = name; 30 | this.numSamples = numSamples; 31 | this.bitsPerSample = bitsPerSample; 32 | this.planes = planes; 33 | } 34 | 35 | // since each format calls this method I've located it in PixelFormat. But it could be a static method somewhere else 36 | 37 | protected void initializeFileInfo(FileInfo fi, int ftype, int compression, ByteOrder.Value byteOrder, int rows, int cols) 38 | { 39 | fi.fileType = ftype; 40 | fi.compression = compression; 41 | if (byteOrder == ByteOrder.Value.INTEL) 42 | fi.intelByteOrder = true; 43 | else 44 | fi.intelByteOrder = false; 45 | fi.height = rows; 46 | fi.width = cols; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /tests/ij/io/RgbFormat.java: -------------------------------------------------------------------------------- 1 | package ij.io; 2 | 3 | /** 4 | * TODO 5 | * 6 | * @author Barry DeZonia 7 | */ 8 | public class RgbFormat extends PixelFormat { 9 | 10 | RgbFormat() 11 | { 12 | super("Rgb",3,8,1); // super(String name, int numSamples, int bitsPerSample, int planes) 13 | } 14 | 15 | @Override 16 | boolean canDoImageCombo(int compression, ByteOrder.Value byteOrder, int headerBytes, boolean stripped) 17 | { 18 | if (compression == FileInfo.COMPRESSION_UNKNOWN) 19 | return false; 20 | if (compression == FileInfo.JPEG) // TODO: remove this restriction to test jpeg compression 21 | return false; 22 | 23 | if (byteOrder == ByteOrder.Value.INTEL) 24 | return false; 25 | 26 | if (stripped && (compression == FileInfo.COMPRESSION_NONE)) 27 | return false; 28 | 29 | return true; 30 | } 31 | 32 | @Override 33 | byte[] nativeBytes(long pix, ByteOrder.Value byteOrder) 34 | { 35 | byte[] output = new byte[3]; 36 | 37 | output[0] = (byte)((pix & 0xff0000) >> 16); 38 | output[1] = (byte)((pix & 0x00ff00) >> 8); 39 | output[2] = (byte)((pix & 0x0000ff) >> 0); 40 | 41 | return output; 42 | } 43 | 44 | @Override 45 | byte[] getBytes(long[][] image, int compression, ByteOrder.Value byteOrder, int headerBytes, boolean inStrips, FileInfo fi) 46 | { 47 | initializeFileInfo(fi,FileInfo.RGB,compression,byteOrder,image.length,image[0].length); 48 | 49 | byte[] output; 50 | 51 | if (inStrips) 52 | output = PixelArranger.arrangeInStrips(this,image,fi); 53 | else 54 | output = PixelArranger.arrangeContiguously(this,image,fi); 55 | 56 | output = PixelArranger.attachHeader(fi,headerBytes,output); 57 | 58 | return output; 59 | 60 | } 61 | 62 | @Override 63 | Object expectedResults(long[][] inputImage) 64 | { 65 | int[] output = new int[inputImage.length * inputImage[0].length]; 66 | 67 | // NOTICE that input is rgb but output is argb 68 | 69 | int i = 0; 70 | for (long[] row : inputImage) 71 | for (long pix : row) 72 | output[i++] = (int)(0xff000000 | (pix & 0xffffff)); 73 | 74 | return output; 75 | } 76 | 77 | @Override 78 | Object pixelsFromBytes(byte[] bytes, ByteOrder.Value order) 79 | { 80 | int numInts = bytes.length / 3; 81 | int[] output = new int[numInts]; 82 | for (int i = 0; i < numInts; i++) 83 | output[i] = 0xff000000 | ((bytes[3*i] & 0xff) << 16) | ((bytes[3*i+1] & 0xff) << 8) | ((bytes[3*i+2] & 0xff) << 0); 84 | return output; 85 | } 86 | } 87 | 88 | -------------------------------------------------------------------------------- /tests/ij/io/RgbPlanarFormat.java: -------------------------------------------------------------------------------- 1 | package ij.io; 2 | 3 | /** 4 | * TODO 5 | * 6 | * @author Barry DeZonia 7 | */ 8 | public class RgbPlanarFormat extends PixelFormat { 9 | 10 | RgbPlanarFormat() 11 | { 12 | super("RgbPlanar",3,8,3); // super(String name, int numSamples, int bitsPerSample, int planes) 13 | } 14 | 15 | @Override 16 | boolean canDoImageCombo(int compression, ByteOrder.Value byteOrder, int headerBytes, boolean stripped) 17 | { 18 | if (compression == FileInfo.COMPRESSION_UNKNOWN) 19 | return false; 20 | if (compression == FileInfo.JPEG) // TODO: remove this restriction to test jpeg compression 21 | return false; 22 | 23 | if (byteOrder == ByteOrder.Value.INTEL) 24 | return false; 25 | 26 | if (stripped && (compression == FileInfo.COMPRESSION_NONE)) 27 | return false; 28 | 29 | return true; 30 | } 31 | 32 | @Override 33 | byte[] nativeBytes(long pix, ByteOrder.Value byteOrder) 34 | { 35 | byte[] output = new byte[3]; 36 | 37 | output[0] = (byte)((pix & 0x00ff0000) >> 16); 38 | output[1] = (byte)((pix & 0x0000ff00) >> 8); 39 | output[2] = (byte)((pix & 0x000000ff) >> 0); 40 | 41 | return output; 42 | } 43 | 44 | @Override 45 | byte[] getBytes(long[][] image, int compression, ByteOrder.Value byteOrder, int headerBytes, boolean inStrips, FileInfo fi) 46 | { 47 | initializeFileInfo(fi,FileInfo.RGB_PLANAR,compression,byteOrder,image.length,image[0].length); 48 | 49 | byte[] output = PixelArranger.arrangeAsPlanes(this, image, fi, inStrips, false); 50 | 51 | output = PixelArranger.attachHeader(fi,headerBytes,output); 52 | 53 | return output; 54 | } 55 | 56 | @Override 57 | Object expectedResults(long[][] inputImage) 58 | { 59 | int[] output = new int[inputImage.length * inputImage[0].length]; 60 | 61 | // NOTICE input is rgb planar but output is argb 62 | 63 | int i = 0; 64 | for (long[] row : inputImage) 65 | for (long pix : row) 66 | output[i++] = (int)(0xff000000 | (pix & 0xffffff)); 67 | 68 | return output; 69 | } 70 | 71 | @Override 72 | Object pixelsFromBytes(byte[] bytes, ByteOrder.Value order) 73 | { 74 | // this method not tested by ImageWriter. Therefore no implementation until it will be used. 75 | return null; 76 | } 77 | } 78 | 79 | -------------------------------------------------------------------------------- /tests/ij/io/TwelveBitEncoder.java: -------------------------------------------------------------------------------- 1 | package ij.io; 2 | 3 | /** 4 | * TODO 5 | * 6 | * @author Barry DeZonia 7 | */ 8 | public class TwelveBitEncoder { 9 | 10 | TwelveBitEncoder() {} 11 | 12 | static public byte[] encode(long[][] inPix) 13 | { 14 | int rows = inPix.length; 15 | int cols = inPix[0].length; 16 | 17 | int bytesPerRow = (int) Math.ceil(cols * 1.5); // 1.5 bytes per pix 18 | 19 | byte[] output = new byte[rows * bytesPerRow]; 20 | 21 | int o = 0; 22 | for (int r = 0; r < rows; r++) 23 | for (int c = 0; c < cols; c++) 24 | if (c%2 == 0) // even numbered column 25 | { 26 | // set this byte's 8 bits plus next byte's high 4 bits 27 | // use 12 bits of the input int 28 | output[o] = (byte)((inPix[r][c] & 0xff0) >> 4) ; 29 | output[o+1] = (byte)((inPix[r][c] & 0x00f) << 4); 30 | o += 1; // finished 1 pixel 31 | if (c == cols-1) 32 | o += 1; // if end of row then next pixel completed also 33 | } 34 | else // odd numbered column 35 | { 36 | // set this byte's low 4 bits and next byte's 8 bits 37 | // use 12 bits of the input int 38 | output[o] = (byte)(output[o] | ((inPix[r][c] & 0xf00) >> 8)); 39 | output[o+1] = (byte)(inPix[r][c] & 0x0ff); 40 | o += 2; // finished 2 pixels 41 | } 42 | 43 | return output; 44 | } 45 | } 46 | 47 | -------------------------------------------------------------------------------- /tests/ij/macro/ReturnExceptionTest.java: -------------------------------------------------------------------------------- 1 | package ij.macro; 2 | 3 | import org.junit.Test; 4 | 5 | /** 6 | * Unit tests for {@link ReturnException}. 7 | * 8 | * @author Barry DeZonia 9 | */ 10 | public class ReturnExceptionTest { 11 | 12 | @Test 13 | public void testReturnException() 14 | { 15 | new ReturnException(); 16 | //Not sure how to test this. 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /tests/ij/macro/SymbolTest.java: -------------------------------------------------------------------------------- 1 | package ij.macro; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import org.junit.Test; 6 | 7 | /** 8 | * Unit tests for {@link Symbol}. 9 | * 10 | * @author Barry DeZonia 11 | */ 12 | public class SymbolTest { 13 | 14 | @Test 15 | public void testSymbolIntString() 16 | { 17 | String testString = "TestText"; 18 | int a = MacroConstants.TOK_SHIFT; 19 | Symbol st = new Symbol( a, testString ); 20 | assertEquals( st.toString(), (a&0xffff)+" 0.0 "+testString ); 21 | } 22 | 23 | @Test 24 | public void testSymbolDouble() 25 | { 26 | double testValue = 1.1; 27 | Symbol st = new Symbol( testValue ); 28 | assertEquals( st.toString(), "0 1.1 null" ); 29 | } 30 | 31 | @Test 32 | public void testGetFunctionType() 33 | { 34 | String testString = "TestText"; 35 | int a = MacroConstants.INVERT; 36 | Symbol st = new Symbol( a, testString ); 37 | assertEquals( st.getFunctionType(), 134 ); 38 | 39 | a = MacroConstants.GET_ZOOM; 40 | st = new Symbol( a, testString ); 41 | assertEquals( st.getFunctionType(), 135 ); 42 | 43 | a = MacroConstants.SELECTION_NAME; 44 | st = new Symbol( a, testString ); 45 | assertEquals( st.getFunctionType(), 136 ); 46 | 47 | a = MacroConstants.ARRAY_FUNC; 48 | st = new Symbol( a, testString ); 49 | assertEquals( st.getFunctionType(), 137 ); 50 | 51 | } 52 | 53 | @Test 54 | public void testToString() { 55 | double testValue = 1.1; 56 | Symbol st = new Symbol( testValue ); 57 | assertEquals( st.toString(), "0 1.1 null" ); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /tests/ij/measure/CalibrationTools.java: -------------------------------------------------------------------------------- 1 | package ij.measure; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import java.lang.reflect.Field; 6 | 7 | /** 8 | * Utility methods for testing {@link Calibration} objects. 9 | * 10 | * @author Barry DeZonia 11 | * @author Curtis Rueden 12 | */ 13 | public final class CalibrationTools { 14 | 15 | private CalibrationTools() { 16 | // prevent instantiation of utility class 17 | } 18 | 19 | /** 20 | * Compares two Calibration objects for deep equality. Tests more internals of 21 | * a Calibration than equals() does. 22 | */ 23 | public static void assertCalibrationsEqual(final Calibration c1, 24 | final Calibration c2) 25 | { 26 | if (c1 == c2) return; 27 | assertEquals(c1.pixelWidth, c2.pixelWidth, 0); 28 | assertEquals(c1.pixelHeight, c2.pixelHeight, 0); 29 | assertEquals(c1.pixelDepth, c2.pixelDepth, 0); 30 | assertEquals(c1.frameInterval, c2.frameInterval, 0); 31 | assertEquals(c1.fps, c2.fps, 0); 32 | assertEquals(c1.loop, c2.loop); 33 | assertEquals(c1.xOrigin, c2.xOrigin, 0); 34 | assertEquals(c1.yOrigin, c2.yOrigin, 0); 35 | assertEquals(c1.zOrigin, c2.zOrigin, 0); 36 | assertEquals(c1.info, c2.info); 37 | assertFieldsEqual(c1, c2, "coefficients"); 38 | assertFieldsEqual(c1, c2, "unit"); 39 | assertFieldsEqual(c1, c2, "yunit"); 40 | assertFieldsEqual(c1, c2, "zunit"); 41 | assertFieldsEqual(c1, c2, "units"); 42 | assertFieldsEqual(c1, c2, "valueUnit"); 43 | assertFieldsEqual(c1, c2, "timeUnit"); 44 | assertFieldsEqual(c1, c2, "function"); 45 | assertFieldsEqual(c1, c2, "cTable"); 46 | assertFieldsEqual(c1, c2, "invertedLut"); 47 | assertFieldsEqual(c1, c2, "bitDepth"); 48 | assertFieldsEqual(c1, c2, "zeroClip"); 49 | assertFieldsEqual(c1, c2, "invertY"); 50 | } 51 | 52 | private static void assertFieldsEqual(final Calibration c1, 53 | final Calibration c2, final String field) 54 | { 55 | assertEquals(get(c1, field), get(c2, field)); 56 | } 57 | 58 | private static Object get(final Calibration c, final String field) { 59 | try { 60 | final Field f = c.getClass().getDeclaredField(field); 61 | f.setAccessible(true); 62 | return f.get(c); 63 | } 64 | catch (final Exception e) { 65 | throw new IllegalArgumentException("Invalid field: " + field, e); 66 | } 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /tests/ij/measure/MeasurementsTest.java: -------------------------------------------------------------------------------- 1 | package ij.measure; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import org.junit.Test; 6 | 7 | /** 8 | * Unit tests for {@link Measurements}. 9 | * 10 | * @author Barry DeZonia 11 | */ 12 | public class MeasurementsTest { 13 | @Test 14 | public void testConstants() 15 | { 16 | assertEquals(1,Measurements.AREA); 17 | assertEquals(2,Measurements.MEAN); 18 | assertEquals(4,Measurements.STD_DEV); 19 | assertEquals(8,Measurements.MODE); 20 | assertEquals(16,Measurements.MIN_MAX); 21 | assertEquals(32,Measurements.CENTROID); 22 | assertEquals(64,Measurements.CENTER_OF_MASS); 23 | assertEquals(128,Measurements.PERIMETER); 24 | assertEquals(256,Measurements.LIMIT); 25 | assertEquals(512,Measurements.RECT); 26 | assertEquals(1024,Measurements.LABELS); 27 | assertEquals(2048,Measurements.ELLIPSE); 28 | assertEquals(4096,Measurements.INVERT_Y); 29 | assertEquals(8192,Measurements.CIRCULARITY); 30 | assertEquals(8192,Measurements.SHAPE_DESCRIPTORS); 31 | assertEquals(16384,Measurements.FERET); 32 | assertEquals(0x8000,Measurements.INTEGRATED_DENSITY); 33 | assertEquals(0x10000,Measurements.MEDIAN); 34 | assertEquals(0x20000,Measurements.SKEWNESS); 35 | assertEquals(0x40000,Measurements.KURTOSIS); 36 | assertEquals(0x80000,Measurements.AREA_FRACTION); 37 | assertEquals(0x100000,Measurements.SLICE); 38 | assertEquals(0x100000,Measurements.STACK_POSITION); 39 | assertEquals(0x200000,Measurements.SCIENTIFIC_NOTATION); 40 | assertEquals(20,Measurements.MAX_STANDARDS); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /tests/ij/process/DataConstants.java: -------------------------------------------------------------------------------- 1 | package ij.process; 2 | 3 | /** 4 | * TODO 5 | * 6 | * @author Barry DeZonia 7 | */ 8 | public class DataConstants { 9 | 10 | public static final String DATA_DIR = "src/test/resources/data/"; 11 | 12 | } 13 | -------------------------------------------------------------------------------- /tests/ij/util/StringSorterTest.java: -------------------------------------------------------------------------------- 1 | package ij.util; 2 | 3 | import static org.junit.Assert.assertTrue; 4 | 5 | import java.util.Arrays; 6 | import java.util.Collections; 7 | import java.util.List; 8 | 9 | import org.junit.Test; 10 | 11 | /** 12 | * Unit tests for {@link StringSorter}. 13 | * 14 | * @author Barry DeZonia 15 | */ 16 | public class StringSorterTest { 17 | 18 | // make sure that StringSorter's implementation matches a known good sort algo: Java's Collections.sort 19 | private void testThisStringArray(String[] strings) 20 | { 21 | String[] dupes = strings.clone(); 22 | 23 | // create the baseline case from Java's API 24 | List baselineList = Arrays.asList(strings); 25 | Collections.sort(baselineList); 26 | 27 | // create the IJ case from StringSorter 28 | StringSorter.sort(dupes); 29 | List dupesList = Arrays.asList(dupes); 30 | 31 | // compare the two lists using equals() 32 | assertTrue(dupesList.equals(baselineList)); 33 | } 34 | 35 | @Test 36 | public void testSortStringArray() { 37 | 38 | // zero items 39 | testThisStringArray(new String[] {}); 40 | 41 | // one item 42 | testThisStringArray(new String[] {"1"}); 43 | 44 | // some two item tests 45 | testThisStringArray(new String[] {"1","2"}); 46 | testThisStringArray(new String[] {"2","1"}); 47 | 48 | // some three item tests 49 | testThisStringArray(new String[] {"1","2","3"}); 50 | testThisStringArray(new String[] {"1","3","2"}); 51 | testThisStringArray(new String[] {"2","1","3"}); 52 | testThisStringArray(new String[] {"2","3","1"}); 53 | testThisStringArray(new String[] {"3","1","2"}); 54 | testThisStringArray(new String[] {"3","2","1"}); 55 | 56 | // some four item tests 57 | testThisStringArray(new String[] {"a","a","a","a"}); 58 | testThisStringArray(new String[] {"1","0","1","0"}); 59 | testThisStringArray(new String[] {"0","0","1","1"}); 60 | testThisStringArray(new String[] {"1","1","0","0"}); 61 | testThisStringArray(new String[] {"","","",""}); 62 | 63 | // a random String array 64 | testThisStringArray(new String[] {"d4","--","81q","11x", "ASDF","#$%^","\\][|}{","PO23aa!"}); 65 | } 66 | 67 | } 68 | --------------------------------------------------------------------------------