Hello!

To see the file structure, click on "tree".

Note that updates take place every 10 minutes, commits may not be seen immediately.
Annotation Project with new structure of packages.
authorlingutln <lingutln@localhost>
Tue, 13 Dec 2011 22:54:54 +0000 (22:54 +0000)
committerlingutln <lingutln@localhost>
Tue, 13 Dec 2011 22:54:54 +0000 (22:54 +0000)
svn path=/; revision=223

1047 files changed:
Annotation/.classpath [new file with mode: 0644]
Annotation/.gitignore [deleted file]
Annotation/.project [new file with mode: 0644]
Annotation/.settings/org.eclipse.jdt.core.prefs [new file with mode: 0644]
Annotation/META-INF/ECLIPSE.RSA [new file with mode: 0644]
Annotation/META-INF/ECLIPSE.SF [new file with mode: 0644]
Annotation/META-INF/MANIFEST.MF [new file with mode: 0644]
Annotation/META-INF/eclipse.inf [new file with mode: 0644]
Annotation/about.html [new file with mode: 0644]
Annotation/external.xpt [new file with mode: 0644]
Annotation/plugin.properties [new file with mode: 0644]
Annotation/plugins/BPTPlugin.plugin/bptplugin.jar [new file with mode: 0644]
Annotation/plugins/BPTPlugin.plugin/jbpt.dll [new file with mode: 0644]
Annotation/plugins/BPTPlugin.plugin/libjbpt.jnilib [new file with mode: 0644]
Annotation/plugins/BPTPlugin.plugin/libjbpt.so [new file with mode: 0644]
Annotation/plugins/BPTPlugin.plugin/libjbpt64.so [new file with mode: 0644]
Annotation/plugins/BPTPlugin.plugin/plugin.xml [new file with mode: 0644]
Annotation/plugins/IGCPlugin.plugin/igcplugin.jar [new file with mode: 0644]
Annotation/plugins/IGCPlugin.plugin/jigc.dll [new file with mode: 0644]
Annotation/plugins/IGCPlugin.plugin/libjigc.jnilib [new file with mode: 0644]
Annotation/plugins/IGCPlugin.plugin/libjigc.so [new file with mode: 0644]
Annotation/plugins/IGCPlugin.plugin/libjigc64.so [new file with mode: 0644]
Annotation/plugins/IGCPlugin.plugin/plugin.xml [new file with mode: 0644]
Annotation/plugins/SIOXPlugin.plugin/plugin.xml [new file with mode: 0644]
Annotation/plugins/SIOXPlugin.plugin/sioxapi.jar [new file with mode: 0644]
Annotation/plugins/SIOXPlugin.plugin/sioxplugin.jar [new file with mode: 0644]
Annotation/plugins/SRGPlugin.plugin/jsrg.dll [new file with mode: 0644]
Annotation/plugins/SRGPlugin.plugin/libjsrg.jnilib [new file with mode: 0644]
Annotation/plugins/SRGPlugin.plugin/libjsrg.so [new file with mode: 0644]
Annotation/plugins/SRGPlugin.plugin/libjsrg64.so [new file with mode: 0644]
Annotation/plugins/SRGPlugin.plugin/plugin.xml [new file with mode: 0644]
Annotation/plugins/SRGPlugin.plugin/srgplugin.jar [new file with mode: 0644]
Annotation/resources/ant/lib/ant-deb.jar [new file with mode: 0644]
Annotation/resources/ant/lib/ant-gzip2.jar [new file with mode: 0644]
Annotation/resources/ant/lib/ant-passwd-task.jar [new file with mode: 0644]
Annotation/resources/ant/lib/ant-swt-identify.jar [new file with mode: 0644]
Annotation/resources/ant/lib/jsmoothgen-ant.jar [new file with mode: 0644]
Annotation/resources/ant/lib/standalone-compiler.jar [new file with mode: 0644]
Annotation/resources/ant/properties [new file with mode: 0644]
Annotation/resources/config/actions.mac.properties [new file with mode: 0644]
Annotation/resources/config/actions.properties [new file with mode: 0644]
Annotation/resources/config/application.mac.properties [new file with mode: 0644]
Annotation/resources/config/application.properties [new file with mode: 0644]
Annotation/resources/config/view.properties [new file with mode: 0644]
Annotation/resources/doc/help.html [new file with mode: 0644]
Annotation/resources/icons/about-box.png [new file with mode: 0644]
Annotation/resources/icons/about.png [new file with mode: 0644]
Annotation/resources/icons/application.png [new file with mode: 0644]
Annotation/resources/icons/apply.png [new file with mode: 0644]
Annotation/resources/icons/auto.png [new file with mode: 0644]
Annotation/resources/icons/background.png [new file with mode: 0644]
Annotation/resources/icons/brush.png [new file with mode: 0644]
Annotation/resources/icons/clear.png [new file with mode: 0644]
Annotation/resources/icons/close.png [new file with mode: 0644]
Annotation/resources/icons/copy.png [new file with mode: 0644]
Annotation/resources/icons/dialog-error.png [new file with mode: 0644]
Annotation/resources/icons/dialog-information.png [new file with mode: 0644]
Annotation/resources/icons/dialog-warning.png [new file with mode: 0644]
Annotation/resources/icons/exit.png [new file with mode: 0644]
Annotation/resources/icons/experiment.png [new file with mode: 0644]
Annotation/resources/icons/export.png [new file with mode: 0644]
Annotation/resources/icons/foreground.png [new file with mode: 0644]
Annotation/resources/icons/help.png [new file with mode: 0644]
Annotation/resources/icons/html.png [new file with mode: 0644]
Annotation/resources/icons/icon-16.png [new file with mode: 0644]
Annotation/resources/icons/icon-24.png [new file with mode: 0644]
Annotation/resources/icons/icon-32.png [new file with mode: 0644]
Annotation/resources/icons/icon-48.png [new file with mode: 0644]
Annotation/resources/icons/image.png [new file with mode: 0644]
Annotation/resources/icons/next.png [new file with mode: 0644]
Annotation/resources/icons/open-recent.png [new file with mode: 0644]
Annotation/resources/icons/open.png [new file with mode: 0644]
Annotation/resources/icons/preferences.png [new file with mode: 0644]
Annotation/resources/icons/previous.png [new file with mode: 0644]
Annotation/resources/icons/print.png [new file with mode: 0644]
Annotation/resources/icons/redo.png [new file with mode: 0644]
Annotation/resources/icons/refresh.png [new file with mode: 0644]
Annotation/resources/icons/reset.png [new file with mode: 0644]
Annotation/resources/icons/run.png [new file with mode: 0644]
Annotation/resources/icons/save-as.png [new file with mode: 0644]
Annotation/resources/icons/save.png [new file with mode: 0644]
Annotation/resources/icons/undo.png [new file with mode: 0644]
Annotation/resources/icons/view.png [new file with mode: 0644]
Annotation/resources/icons/zoom-best-fit.png [new file with mode: 0644]
Annotation/resources/icons/zoom-in.png [new file with mode: 0644]
Annotation/resources/icons/zoom-original.png [new file with mode: 0644]
Annotation/resources/icons/zoom-out.png [new file with mode: 0644]
Annotation/resources/plaf/debian/changelog [new file with mode: 0644]
Annotation/resources/plaf/debian/copyright [new file with mode: 0644]
Annotation/resources/plaf/debian/desktop [new file with mode: 0644]
Annotation/resources/plaf/debian/ist [new file with mode: 0644]
Annotation/resources/plaf/debian/ist.1 [new file with mode: 0644]
Annotation/resources/plaf/debian/postinst [new file with mode: 0644]
Annotation/resources/plaf/debian/postrm [new file with mode: 0644]
Annotation/resources/plaf/linux/ist [new file with mode: 0644]
Annotation/resources/plaf/mac/Info.plist [new file with mode: 0644]
Annotation/resources/plaf/mac/PkgInfo [new file with mode: 0644]
Annotation/resources/plaf/mac/icon.icns [new file with mode: 0644]
Annotation/resources/plaf/mac/ist [new file with mode: 0644]
Annotation/resources/plaf/windows/application.ico [new file with mode: 0644]
Annotation/resources/plaf/windows/install.xml [new file with mode: 0644]
Annotation/resources/plaf/windows/installer.ico [new file with mode: 0644]
Annotation/resources/plaf/windows/installer.jsmooth [new file with mode: 0644]
Annotation/resources/plaf/windows/ist.jsmooth [new file with mode: 0644]
Annotation/resources/plaf/windows/shortcuts.xml [new file with mode: 0644]
Annotation/resources/plaf/windows/skeletons/windowed-wrapper/description.skel [new file with mode: 0644]
Annotation/resources/plaf/windows/skeletons/windowed-wrapper/jwrap.exe [new file with mode: 0755]
Annotation/src/ie/dcu/apps/ist/AppPrefs.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/AppPrefsManager.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/AppRecentFiles.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/AppRecentMenu.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/AppStatus.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/AppWindow.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/Application.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/EvaluatorRegistry.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/Main.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/PainterRegistry.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/SegmenterRegistry.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/actions/AboutAction.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/actions/ActionManager.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/actions/AppAction.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/actions/ConfigureSegmenterAction.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/actions/ConfiguredAction.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/actions/CopyAction.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/actions/ExitAction.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/actions/ExportImageMapAction.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/actions/ExportTransparentPNGAction.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/actions/ExportViewAction.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/actions/HelpAction.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/actions/HoverAction.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/actions/HoverMenuManager.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/actions/IHoverAction.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/actions/NextAction.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/actions/OpenAction.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/actions/OpenExperimentAction.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/actions/OpenRecentAction.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/actions/PreferencesAction.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/actions/PreviousAction.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/actions/PrintAction.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/actions/RedoAction.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/actions/SaveAction.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/actions/SaveAsAction.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/actions/SelectSegmenterAction.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/actions/UndoAction.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/controllers/AnnotationTool.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/controllers/MouseMotionAdapter.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/dialogs/ExportDialog.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/dialogs/PrefsDialog.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/event/ContextChangeListener.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/event/ContextChangedEvent.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/event/StateEvent.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/event/StateListener.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/event/TickerEvent.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/event/TickerListener.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/event/TimeoutEvent.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/event/TimeoutListener.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/exp/Experiment.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/exp/ExperimentFactory.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/exp/ExperimentManager.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/exp/ExperimentResults.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/exp/FormatException.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/exp/StorageSelection.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/exp/Task.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/export/imagemap/AreaShape.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/export/imagemap/ExportException.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/export/imagemap/Exporter.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/export/imagemap/HtmlTag.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/export/imagemap/ImageMap.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/export/imagemap/MapArea.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/export/imagemap/RolloverEffect.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/export/imagemap/template.html [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/recent/RecentFiles.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/recent/RecentFilesEvent.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/recent/RecentFilesListener.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/views/ExperimentPanel.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/views/SegmentationView.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/widgets/AnnotatedImageControl.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/widgets/BrushControl.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/widgets/ColorSelector.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/widgets/ImageMenuManager.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/widgets/SwtTimer.java [new file with mode: 0644]
Annotation/src/ie/dcu/apps/ist/widgets/Ticker.java [new file with mode: 0644]
Annotation/src/ie/dcu/array/Arrays.class [new file with mode: 0644]
Annotation/src/ie/dcu/array/Arrays.java [new file with mode: 0644]
Annotation/src/ie/dcu/array/Filter$Byte.class [new file with mode: 0644]
Annotation/src/ie/dcu/array/Filter$Double.class [new file with mode: 0644]
Annotation/src/ie/dcu/array/Filter$Float.class [new file with mode: 0644]
Annotation/src/ie/dcu/array/Filter$Integer.class [new file with mode: 0644]
Annotation/src/ie/dcu/array/Filter$Long.class [new file with mode: 0644]
Annotation/src/ie/dcu/array/Filter$Short.class [new file with mode: 0644]
Annotation/src/ie/dcu/array/Filter.class [new file with mode: 0644]
Annotation/src/ie/dcu/array/Filter.java [new file with mode: 0644]
Annotation/src/ie/dcu/array/Reduction$Double.class [new file with mode: 0644]
Annotation/src/ie/dcu/array/Reduction$Long.class [new file with mode: 0644]
Annotation/src/ie/dcu/array/Reduction.class [new file with mode: 0644]
Annotation/src/ie/dcu/array/Reduction.java [new file with mode: 0644]
Annotation/src/ie/dcu/auto/AutomationData$Listener.class [new file with mode: 0644]
Annotation/src/ie/dcu/auto/AutomationData.class [new file with mode: 0644]
Annotation/src/ie/dcu/auto/AutomationData.java [new file with mode: 0644]
Annotation/src/ie/dcu/auto/AutomationDataAdapter.class [new file with mode: 0644]
Annotation/src/ie/dcu/auto/AutomationDataAdapter.java [new file with mode: 0644]
Annotation/src/ie/dcu/auto/AutomationInput.class [new file with mode: 0644]
Annotation/src/ie/dcu/auto/AutomationInput.java [new file with mode: 0644]
Annotation/src/ie/dcu/auto/Constants.class [new file with mode: 0644]
Annotation/src/ie/dcu/auto/Constants.java [new file with mode: 0644]
Annotation/src/ie/dcu/auto/EvaluationResults$Item.class [new file with mode: 0644]
Annotation/src/ie/dcu/auto/EvaluationResults.class [new file with mode: 0644]
Annotation/src/ie/dcu/auto/EvaluationResults.java [new file with mode: 0644]
Annotation/src/ie/dcu/auto/MaximaLocator.class [new file with mode: 0644]
Annotation/src/ie/dcu/auto/MaximaLocator.java [new file with mode: 0644]
Annotation/src/ie/dcu/auto/automator/AbstractAutomator.class [new file with mode: 0644]
Annotation/src/ie/dcu/auto/automator/AbstractAutomator.java [new file with mode: 0644]
Annotation/src/ie/dcu/auto/automator/Automator.class [new file with mode: 0644]
Annotation/src/ie/dcu/auto/automator/Automator.java [new file with mode: 0644]
Annotation/src/ie/dcu/auto/automator/AutomatorFactory.class [new file with mode: 0644]
Annotation/src/ie/dcu/auto/automator/AutomatorFactory.java [new file with mode: 0644]
Annotation/src/ie/dcu/auto/automator/DeterministicAutomator.class [new file with mode: 0644]
Annotation/src/ie/dcu/auto/automator/DeterministicAutomator.java [new file with mode: 0644]
Annotation/src/ie/dcu/auto/automator/NonDeterministicAutomator1.class [new file with mode: 0644]
Annotation/src/ie/dcu/auto/automator/NonDeterministicAutomator1.java [new file with mode: 0644]
Annotation/src/ie/dcu/auto/automator/NonDeterministicAutomator2.class [new file with mode: 0644]
Annotation/src/ie/dcu/auto/automator/NonDeterministicAutomator2.java [new file with mode: 0644]
Annotation/src/ie/dcu/auto/automator/NonDeterministicAutomator3.class [new file with mode: 0644]
Annotation/src/ie/dcu/auto/automator/NonDeterministicAutomator3.java [new file with mode: 0644]
Annotation/src/ie/dcu/eval/AbstractEvaluator.class [new file with mode: 0644]
Annotation/src/ie/dcu/eval/AbstractEvaluator.java [new file with mode: 0644]
Annotation/src/ie/dcu/eval/BestEvaluator.class [new file with mode: 0644]
Annotation/src/ie/dcu/eval/BestEvaluator.java [new file with mode: 0644]
Annotation/src/ie/dcu/eval/BinaryClassifierEvaluation.class [new file with mode: 0644]
Annotation/src/ie/dcu/eval/BinaryClassifierEvaluation.java [new file with mode: 0644]
Annotation/src/ie/dcu/eval/BoundaryAccuracyEvaluator.class [new file with mode: 0644]
Annotation/src/ie/dcu/eval/BoundaryAccuracyEvaluator.java [new file with mode: 0644]
Annotation/src/ie/dcu/eval/ConfusionMatrixEvaluator.class [new file with mode: 0644]
Annotation/src/ie/dcu/eval/ConfusionMatrixEvaluator.java [new file with mode: 0644]
Annotation/src/ie/dcu/eval/Evaluator.class [new file with mode: 0644]
Annotation/src/ie/dcu/eval/Evaluator.java [new file with mode: 0644]
Annotation/src/ie/dcu/graph/dijkstra/Graph$Edge.class [new file with mode: 0644]
Annotation/src/ie/dcu/graph/dijkstra/Graph$Node.class [new file with mode: 0644]
Annotation/src/ie/dcu/graph/dijkstra/Graph.class [new file with mode: 0644]
Annotation/src/ie/dcu/graph/dijkstra/Graph.java [new file with mode: 0644]
Annotation/src/ie/dcu/graph/dijkstra/IntGraph$Edge.class [new file with mode: 0644]
Annotation/src/ie/dcu/graph/dijkstra/IntGraph$Node.class [new file with mode: 0644]
Annotation/src/ie/dcu/graph/dijkstra/IntGraph.class [new file with mode: 0644]
Annotation/src/ie/dcu/graph/dijkstra/IntGraph.java [new file with mode: 0644]
Annotation/src/ie/dcu/image/AbstractImageOp.class [new file with mode: 0644]
Annotation/src/ie/dcu/image/AbstractImageOp.java [new file with mode: 0644]
Annotation/src/ie/dcu/image/ContourTracer$Candidate.class [new file with mode: 0644]
Annotation/src/ie/dcu/image/ContourTracer.class [new file with mode: 0644]
Annotation/src/ie/dcu/image/ContourTracer.java [new file with mode: 0644]
Annotation/src/ie/dcu/image/ImageOp.class [new file with mode: 0644]
Annotation/src/ie/dcu/image/ImageOp.java [new file with mode: 0644]
Annotation/src/ie/dcu/image/ObjectLabeler.class [new file with mode: 0644]
Annotation/src/ie/dcu/image/ObjectLabeler.java [new file with mode: 0644]
Annotation/src/ie/dcu/image/binary/AbstractBinaryImageOp.class [new file with mode: 0644]
Annotation/src/ie/dcu/image/binary/AbstractBinaryImageOp.java [new file with mode: 0644]
Annotation/src/ie/dcu/image/binary/BinaryImageOp.class [new file with mode: 0644]
Annotation/src/ie/dcu/image/binary/BinaryImageOp.java [new file with mode: 0644]
Annotation/src/ie/dcu/image/binary/DistanceTransformOp.class [new file with mode: 0644]
Annotation/src/ie/dcu/image/binary/DistanceTransformOp.java [new file with mode: 0644]
Annotation/src/ie/dcu/image/binary/MedialAxisTransformOp.class [new file with mode: 0644]
Annotation/src/ie/dcu/image/binary/MedialAxisTransformOp.java [new file with mode: 0644]
Annotation/src/ie/dcu/image/binary/MorphOp$Close.class [new file with mode: 0644]
Annotation/src/ie/dcu/image/binary/MorphOp$Dilate.class [new file with mode: 0644]
Annotation/src/ie/dcu/image/binary/MorphOp$Edge.class [new file with mode: 0644]
Annotation/src/ie/dcu/image/binary/MorphOp$Erode.class [new file with mode: 0644]
Annotation/src/ie/dcu/image/binary/MorphOp$Open.class [new file with mode: 0644]
Annotation/src/ie/dcu/image/binary/MorphOp$Smooth.class [new file with mode: 0644]
Annotation/src/ie/dcu/image/binary/MorphOp.class [new file with mode: 0644]
Annotation/src/ie/dcu/image/binary/MorphOp.java [new file with mode: 0644]
Annotation/src/ie/dcu/image/colormap/ColorMap.class [new file with mode: 0644]
Annotation/src/ie/dcu/image/colormap/ColorMap.java [new file with mode: 0644]
Annotation/src/ie/dcu/image/colormap/ColorMaps$SpecCache.class [new file with mode: 0644]
Annotation/src/ie/dcu/image/colormap/ColorMaps.class [new file with mode: 0644]
Annotation/src/ie/dcu/image/colormap/ColorMaps.java [new file with mode: 0644]
Annotation/src/ie/dcu/image/colormap/LinearColorMap.class [new file with mode: 0644]
Annotation/src/ie/dcu/image/colormap/LinearColorMap.java [new file with mode: 0644]
Annotation/src/ie/dcu/image/dt/DistanceTransform.class [new file with mode: 0644]
Annotation/src/ie/dcu/image/dt/DistanceTransform.java [new file with mode: 0644]
Annotation/src/ie/dcu/image/gray/GrayConvolve.class [new file with mode: 0644]
Annotation/src/ie/dcu/image/gray/GrayConvolve.java [new file with mode: 0644]
Annotation/src/ie/dcu/image/gray/GrayImageOp.class [new file with mode: 0644]
Annotation/src/ie/dcu/image/gray/GrayImageOp.java [new file with mode: 0644]
Annotation/src/ie/dcu/image/gray/LaplaceFilterOp.class [new file with mode: 0644]
Annotation/src/ie/dcu/image/gray/LaplaceFilterOp.java [new file with mode: 0644]
Annotation/src/ie/dcu/matrix/ByteMatrix.class [new file with mode: 0644]
Annotation/src/ie/dcu/matrix/ByteMatrix.java [new file with mode: 0644]
Annotation/src/ie/dcu/matrix/DoubleMatrix.class [new file with mode: 0644]
Annotation/src/ie/dcu/matrix/DoubleMatrix.java [new file with mode: 0644]
Annotation/src/ie/dcu/matrix/FloatMatrix.class [new file with mode: 0644]
Annotation/src/ie/dcu/matrix/FloatMatrix.java [new file with mode: 0644]
Annotation/src/ie/dcu/matrix/Index2D.class [new file with mode: 0644]
Annotation/src/ie/dcu/matrix/Index2D.java [new file with mode: 0644]
Annotation/src/ie/dcu/matrix/IntMatrix.class [new file with mode: 0644]
Annotation/src/ie/dcu/matrix/IntMatrix.java [new file with mode: 0644]
Annotation/src/ie/dcu/matrix/LongMatrix.class [new file with mode: 0644]
Annotation/src/ie/dcu/matrix/LongMatrix.java [new file with mode: 0644]
Annotation/src/ie/dcu/matrix/Matrix$1.class [new file with mode: 0644]
Annotation/src/ie/dcu/matrix/Matrix$Type.class [new file with mode: 0644]
Annotation/src/ie/dcu/matrix/Matrix.class [new file with mode: 0644]
Annotation/src/ie/dcu/matrix/Matrix.java [new file with mode: 0644]
Annotation/src/ie/dcu/matrix/MatrixFormatter$1.class [new file with mode: 0644]
Annotation/src/ie/dcu/matrix/MatrixFormatter.class [new file with mode: 0644]
Annotation/src/ie/dcu/matrix/MatrixFormatter.java [new file with mode: 0644]
Annotation/src/ie/dcu/matrix/MatrixProvider.class [new file with mode: 0644]
Annotation/src/ie/dcu/matrix/MatrixProvider.java [new file with mode: 0644]
Annotation/src/ie/dcu/matrix/ShortMatrix.class [new file with mode: 0644]
Annotation/src/ie/dcu/matrix/ShortMatrix.java [new file with mode: 0644]
Annotation/src/ie/dcu/plugin/JarResource.class [new file with mode: 0644]
Annotation/src/ie/dcu/plugin/Plugin.class [new file with mode: 0644]
Annotation/src/ie/dcu/plugin/Plugin.java [new file with mode: 0644]
Annotation/src/ie/dcu/plugin/PluginClassLoader.class [new file with mode: 0644]
Annotation/src/ie/dcu/plugin/PluginClassLoader.java [new file with mode: 0644]
Annotation/src/ie/dcu/plugin/PluginException.class [new file with mode: 0644]
Annotation/src/ie/dcu/plugin/PluginException.java [new file with mode: 0644]
Annotation/src/ie/dcu/plugin/PluginLoader$1.class [new file with mode: 0644]
Annotation/src/ie/dcu/plugin/PluginLoader$SaxHandler.class [new file with mode: 0644]
Annotation/src/ie/dcu/plugin/PluginLoader.class [new file with mode: 0644]
Annotation/src/ie/dcu/plugin/PluginLoader.java [new file with mode: 0644]
Annotation/src/ie/dcu/plugin/PluginManager.class [new file with mode: 0644]
Annotation/src/ie/dcu/plugin/PluginManager.java [new file with mode: 0644]
Annotation/src/ie/dcu/segment/SegmentationContext.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/SegmentationContext.java [new file with mode: 0644]
Annotation/src/ie/dcu/segment/SegmentationMask.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/SegmentationMask.java [new file with mode: 0644]
Annotation/src/ie/dcu/segment/Segmenter.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/Segmenter.java [new file with mode: 0644]
Annotation/src/ie/dcu/segment/annotate/Annotation.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/annotate/Annotation.java [new file with mode: 0644]
Annotation/src/ie/dcu/segment/annotate/AnnotationAdapter.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/annotate/AnnotationAdapter.java [new file with mode: 0644]
Annotation/src/ie/dcu/segment/annotate/AnnotationEvent$Type.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/annotate/AnnotationEvent.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/annotate/AnnotationEvent.java [new file with mode: 0644]
Annotation/src/ie/dcu/segment/annotate/AnnotationListener.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/annotate/AnnotationListener.java [new file with mode: 0644]
Annotation/src/ie/dcu/segment/annotate/AnnotationManager.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/annotate/AnnotationManager.java [new file with mode: 0644]
Annotation/src/ie/dcu/segment/annotate/AnnotationType$1.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/annotate/AnnotationType.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/annotate/AnnotationType.java [new file with mode: 0644]
Annotation/src/ie/dcu/segment/options/AbstractEditor.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/options/AbstractOption.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/options/AbstractOption.java [new file with mode: 0644]
Annotation/src/ie/dcu/segment/options/ComboEditor.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/options/Conversion.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/options/Conversion.java [new file with mode: 0644]
Annotation/src/ie/dcu/segment/options/ConversionListener.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/options/DecimalOption.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/options/DecimalOption.java [new file with mode: 0644]
Annotation/src/ie/dcu/segment/options/EnumOption.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/options/EnumOption.java [new file with mode: 0644]
Annotation/src/ie/dcu/segment/options/IntegerOption.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/options/IntegerOption.java [new file with mode: 0644]
Annotation/src/ie/dcu/segment/options/Option.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/options/Option.java [new file with mode: 0644]
Annotation/src/ie/dcu/segment/options/OptionEditor.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/options/OptionType.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/options/OptionType.java [new file with mode: 0644]
Annotation/src/ie/dcu/segment/options/SegmenterOptionDialog$1.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/options/SegmenterOptionDialog$StatusListener.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/options/SegmenterOptionDialog.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/options/SegmenterOptionDialog.java [new file with mode: 0644]
Annotation/src/ie/dcu/segment/options/TextEditor$1.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/options/TextEditor$Verifier.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/options/TextEditor.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/options/TextOption.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/options/TextOption.java [new file with mode: 0644]
Annotation/src/ie/dcu/segment/options/ToggleEditor$1.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/options/ToggleEditor$ToggleListener.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/options/ToggleEditor.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/options/ToggleOption.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/options/ToggleOption.java [new file with mode: 0644]
Annotation/src/ie/dcu/segment/painters/CombinedPainter.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/painters/CombinedPainter.java [new file with mode: 0644]
Annotation/src/ie/dcu/segment/painters/ForegroundOnlyPainter.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/painters/ForegroundOnlyPainter.java [new file with mode: 0644]
Annotation/src/ie/dcu/segment/painters/LabelPainter.java [new file with mode: 0644]
Annotation/src/ie/dcu/segment/painters/MarkupPainter.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/painters/MarkupPainter.java [new file with mode: 0644]
Annotation/src/ie/dcu/segment/painters/MaskPainter.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/painters/MaskPainter.java [new file with mode: 0644]
Annotation/src/ie/dcu/segment/painters/OriginalPainter.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/painters/OriginalPainter.java [new file with mode: 0644]
Annotation/src/ie/dcu/segment/painters/OutlineOverlayPainter.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/painters/OutlineOverlayPainter.java [new file with mode: 0644]
Annotation/src/ie/dcu/segment/painters/SegmentationPainter.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/painters/SegmentationPainter.java [new file with mode: 0644]
Annotation/src/ie/dcu/segment/util/AbstractSegmenter.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/util/AbstractSegmenter.java [new file with mode: 0644]
Annotation/src/ie/dcu/segment/util/AnnotationRasterizer$1.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/util/AnnotationRasterizer.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/util/AnnotationRasterizer.java [new file with mode: 0644]
Annotation/src/ie/dcu/segment/util/ImageArgbConverter.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/util/ImageArgbConverter.java [new file with mode: 0644]
Annotation/src/ie/dcu/segment/util/ImageByteConverter.class [new file with mode: 0644]
Annotation/src/ie/dcu/segment/util/ImageByteConverter.java [new file with mode: 0644]
Annotation/src/ie/dcu/stats/InversionMethod$1.class [new file with mode: 0644]
Annotation/src/ie/dcu/stats/InversionMethod.class [new file with mode: 0644]
Annotation/src/ie/dcu/stats/InversionMethod.java [new file with mode: 0644]
Annotation/src/ie/dcu/swt/CocoaUIEnhancer$1.class [new file with mode: 0644]
Annotation/src/ie/dcu/swt/CocoaUIEnhancer$2.class [new file with mode: 0644]
Annotation/src/ie/dcu/swt/CocoaUIEnhancer.class [new file with mode: 0644]
Annotation/src/ie/dcu/swt/CocoaUIEnhancer.java [new file with mode: 0644]
Annotation/src/ie/dcu/swt/CursorFactory.class [new file with mode: 0644]
Annotation/src/ie/dcu/swt/CursorFactory.java [new file with mode: 0644]
Annotation/src/ie/dcu/swt/Dispatcher.class [new file with mode: 0644]
Annotation/src/ie/dcu/swt/Dispatcher.java [new file with mode: 0644]
Annotation/src/ie/dcu/swt/EventDispatcher.class [new file with mode: 0644]
Annotation/src/ie/dcu/swt/EventDispatcher.java [new file with mode: 0644]
Annotation/src/ie/dcu/swt/ImageControl$1.class [new file with mode: 0644]
Annotation/src/ie/dcu/swt/ImageControl$2.class [new file with mode: 0644]
Annotation/src/ie/dcu/swt/ImageControl$3.class [new file with mode: 0644]
Annotation/src/ie/dcu/swt/ImageControl$4.class [new file with mode: 0644]
Annotation/src/ie/dcu/swt/ImageControl.class [new file with mode: 0644]
Annotation/src/ie/dcu/swt/ImageControl.java [new file with mode: 0644]
Annotation/src/ie/dcu/swt/ImageConverter.class [new file with mode: 0644]
Annotation/src/ie/dcu/swt/ImageConverter.java [new file with mode: 0644]
Annotation/src/ie/dcu/swt/MatrixVisualizer.class [new file with mode: 0644]
Annotation/src/ie/dcu/swt/MatrixVisualizer.java [new file with mode: 0644]
Annotation/src/ie/dcu/swt/ObservableImage.class [new file with mode: 0644]
Annotation/src/ie/dcu/swt/ObservableImage.java [new file with mode: 0644]
Annotation/src/ie/dcu/swt/PopupComposite$1.class [new file with mode: 0644]
Annotation/src/ie/dcu/swt/PopupComposite$ActivationListener.class [new file with mode: 0644]
Annotation/src/ie/dcu/swt/PopupComposite.class [new file with mode: 0644]
Annotation/src/ie/dcu/swt/PopupComposite.java [new file with mode: 0644]
Annotation/src/ie/dcu/swt/SwtUtils$1.class [new file with mode: 0644]
Annotation/src/ie/dcu/swt/SwtUtils$Pt.class [new file with mode: 0644]
Annotation/src/ie/dcu/swt/SwtUtils$Rect.class [new file with mode: 0644]
Annotation/src/ie/dcu/swt/SwtUtils.class [new file with mode: 0644]
Annotation/src/ie/dcu/swt/SwtUtils.java [new file with mode: 0644]
Annotation/src/ie/dcu/swt/event/FileDropEvent.class [new file with mode: 0644]
Annotation/src/ie/dcu/swt/event/FileDropEvent.java [new file with mode: 0644]
Annotation/src/ie/dcu/swt/event/FileDropListener.class [new file with mode: 0644]
Annotation/src/ie/dcu/swt/event/FileDropListener.java [new file with mode: 0644]
Annotation/src/ie/dcu/swt/event/ImageEvent.class [new file with mode: 0644]
Annotation/src/ie/dcu/swt/event/ImageEvent.java [new file with mode: 0644]
Annotation/src/ie/dcu/swt/event/ImageListener.class [new file with mode: 0644]
Annotation/src/ie/dcu/swt/event/ImageListener.java [new file with mode: 0644]
Annotation/src/ie/dcu/swt/event/ZoomEvent.class [new file with mode: 0644]
Annotation/src/ie/dcu/swt/event/ZoomEvent.java [new file with mode: 0644]
Annotation/src/ie/dcu/swt/event/ZoomListener.class [new file with mode: 0644]
Annotation/src/ie/dcu/swt/event/ZoomListener.java [new file with mode: 0644]
Annotation/src/ie/dcu/swt/layout/BorderData.class [new file with mode: 0644]
Annotation/src/ie/dcu/swt/layout/BorderData.java [new file with mode: 0644]
Annotation/src/ie/dcu/swt/layout/BorderLayout.class [new file with mode: 0644]
Annotation/src/ie/dcu/swt/layout/BorderLayout.java [new file with mode: 0644]
Annotation/src/ie/dcu/swt/layout/LayoutFactory.class [new file with mode: 0644]
Annotation/src/ie/dcu/swt/layout/LayoutFactory.java [new file with mode: 0644]
Annotation/src/ie/dcu/util/ArrayUtils.class [new file with mode: 0644]
Annotation/src/ie/dcu/util/ArrayUtils.java [new file with mode: 0644]
Annotation/src/ie/dcu/util/FileUtils.class [new file with mode: 0644]
Annotation/src/ie/dcu/util/FileUtils.java [new file with mode: 0644]
Annotation/src/ie/dcu/util/OsUtils.class [new file with mode: 0644]
Annotation/src/ie/dcu/util/OsUtils.java [new file with mode: 0644]
Annotation/src/ie/dcu/util/PropsUtils.class [new file with mode: 0644]
Annotation/src/ie/dcu/util/PropsUtils.java [new file with mode: 0644]
Annotation/src/org/eclipse/core/commands/AbstractHandler.class [new file with mode: 0644]
Annotation/src/org/eclipse/core/commands/AbstractHandlerWithState.class [new file with mode: 0644]
Annotation/src/org/eclipse/core/commands/AbstractParameterValueConverter.class [new file with mode: 0644]
Annotation/src/org/eclipse/core/commands/Category.class [new file with mode: 0644]
Annotation/src/org/eclipse/core/commands/CategoryEvent.class [new file with mode: 0644]
Annotation/src/org/eclipse/core/commands/Command$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/core/commands/Command$2.class [new file with mode: 0644]
Annotation/src/org/eclipse/core/commands/Command.class [new file with mode: 0644]
Annotation/src/org/eclipse/core/commands/CommandEvent.class [new file with mode: 0644]
Annotation/src/org/eclipse/core/commands/CommandManager$ExecutionListener.class [new file with mode: 0644]
Annotation/src/org/eclipse/core/commands/CommandManager.class [new file with mode: 0644]
Annotation/src/org/eclipse/core/commands/CommandManagerEvent.class [new file with mode: 0644]
Annotation/src/org/eclipse/core/commands/ExecutionEvent.class [new file with mode: 0644]
Annotation/src/org/eclipse/core/commands/ExecutionException.class [new file with mode: 0644]
Annotation/src/org/eclipse/core/commands/HandlerEvent.class [new file with mode: 0644]
Annotation/src/org/eclipse/core/commands/ICategoryListener.class [new file with mode: 0644]
Annotation/src/org/eclipse/core/commands/ICommandListener.class [new file with mode: 0644]
Annotation/src/org/eclipse/core/commands/ICommandManagerListener.class [new file with mode: 0644]
Annotation/src/org/eclipse/core/commands/IExecutionListener.class [new file with mode: 0644]
Annotation/src/org/eclipse/core/commands/IExecutionListenerWithChecks.class [new file with mode: 0644]
Annotation/src/org/eclipse/core/commands/IHandler.class [new file with mode: 0644]
Annotation/src/org/eclipse/core/commands/IHandlerAttributes.class [new file with mode: 0644]
Annotation/src/org/eclipse/core/commands/IHandlerListener.class [new file with mode: 0644]
Annotation/src/org/eclipse/core/commands/INamedHandleStateIds.class [new file with mode: 0644]
Annotation/src/org/eclipse/core/commands/IObjectWithState.class [new file with mode: 0644]
Annotation/src/org/eclipse/core/commands/IParameter.class [new file with mode: 0644]
Annotation/src/org/eclipse/core/commands/IParameterTypeListener.class [new file with mode: 0644]
Annotation/src/org/eclipse/core/commands/IParameterValues.class [new file with mode: 0644]
Annotation/src/org/eclipse/core/commands/IStateListener.class [new file with mode: 0644]
Annotation/src/org/eclipse/core/commands/ITypedParameter.class [new file with mode: 0644]
Annotation/src/org/eclipse/core/commands/NamedHandleObjectWithState.class [new file with mode: 0644]
Annotation/src/org/eclipse/core/commands/NotEnabledException.class [new file with mode: 0644]
Annotation/src/org/eclipse/core/commands/NotHandledException.class [new file with mode: 0644]
Annotation/src/org/eclipse/core/commands/ParameterType.class [new file with mode: 0644]
Annotation/src/org/eclipse/core/commands/ParameterTypeEvent.class [new file with mode: 0644]
Annotation/src/org/eclipse/core/commands/ParameterValueConversionException.class [new file with mode: 0644]
Annotation/src/org/eclipse/core/commands/ParameterValuesException.class [new file with mode: 0644]
Annotation/src/org/eclipse/core/commands/Parameterization.class [new file with mode: 0644]
Annotation/src/org/eclipse/core/commands/ParameterizedCommand.class [new file with mode: 0644]
Annotation/src/org/eclipse/core/commands/SerializationException.class [new file with mode: 0644]
Annotation/src/org/eclipse/core/commands/State.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/bindings/Binding.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/bindings/BindingManager.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/bindings/BindingManagerEvent.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/bindings/CachedBindingSet.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/bindings/IBindingManagerListener.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/bindings/ISchemeListener.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/bindings/Scheme.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/bindings/SchemeEvent.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/bindings/Trigger.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/bindings/TriggerSequence.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/bindings/keys/IKeyLookup.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/bindings/keys/KeyBinding.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/bindings/keys/KeyLookupFactory.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/bindings/keys/KeySequence.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/bindings/keys/KeySequenceText$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/bindings/keys/KeySequenceText$2.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/bindings/keys/KeySequenceText$KeyTrapListener.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/bindings/keys/KeySequenceText$TraversalFilter.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/bindings/keys/KeySequenceText$TraversalFilterManager.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/bindings/keys/KeySequenceText$UpdateSequenceListener.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/bindings/keys/KeySequenceText.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/bindings/keys/KeyStroke.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/bindings/keys/ParseException.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/bindings/keys/SWTKeyLookup.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/bindings/keys/SWTKeySupport.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/AnimatorFactory.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/ControlAnimator.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/ControlEnableState$ItemState.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/ControlEnableState.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/Dialog$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/Dialog$2.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/Dialog.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/DialogMessageArea.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/DialogPage.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/DialogSettings$XMLWriter.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/DialogSettings.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/DialogTray.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/ErrorDialog$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/ErrorDialog.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/ErrorSupportProvider.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/IDialogBlockedHandler.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/IDialogConstants.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/IDialogPage.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/IDialogSettings.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/IInputValidator.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/IMessageProvider.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/IPageChangeProvider.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/IPageChangedListener.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/IPageChangingListener.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/IconAndMessageDialog$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/IconAndMessageDialog$2.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/IconAndMessageDialog.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/ImageAndMessageArea$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/ImageAndMessageArea$2.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/ImageAndMessageArea.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/InputDialog$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/InputDialog.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/MessageDialog.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/MessageDialogWithToggle$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/MessageDialogWithToggle.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/PageChangedEvent.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/PageChangingEvent.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/PopupDialog$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/PopupDialog$2.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/PopupDialog$3.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/PopupDialog$4.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/PopupDialog$5.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/PopupDialog$6.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/PopupDialog$7.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/PopupDialog$MoveAction.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/PopupDialog$PersistBoundsAction.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/PopupDialog$ResizeAction.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/PopupDialog.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/ProgressIndicator.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/ProgressMonitorDialog$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/ProgressMonitorDialog$2.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/ProgressMonitorDialog$3.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/ProgressMonitorDialog$ProgressMonitor.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/ProgressMonitorDialog.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/StatusDialog$MessageLine.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/StatusDialog.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/TitleAreaDialog$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/TitleAreaDialog.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/TrayDialog$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/TrayDialog$2.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/TrayDialog$3.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/TrayDialog$4.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/dialogs/TrayDialog.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/AutoCompleteField.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/ComboContentAdapter.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$10.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$11.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$12.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$13.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$14.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$2.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$3.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$4.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$5.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$6.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$7.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$8.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$9.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$ContentProposalPopup$InfoPopupDialog.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$ContentProposalPopup$PopupCloserListener.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$ContentProposalPopup$TargetControlListener.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$ContentProposalPopup.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/ControlDecoration$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/ControlDecoration$2.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/ControlDecoration$3.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/ControlDecoration$4.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/ControlDecoration$5.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/ControlDecoration$6.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/ControlDecoration$7.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/ControlDecoration$8.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/ControlDecoration$Hover.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/ControlDecoration.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/DecoratedField$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/DecoratedField$2.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/DecoratedField$3.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/DecoratedField$4.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/DecoratedField$5.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/DecoratedField$FieldDecorationData.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/DecoratedField$Hover.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/DecoratedField.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/FieldAssistColors$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/FieldAssistColors.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/FieldDecoration.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/FieldDecorationRegistry$Entry.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/FieldDecorationRegistry.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/IContentProposal.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/IContentProposalListener.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/IContentProposalListener2.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/IContentProposalProvider.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/IControlContentAdapter.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/IControlCreator.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/SimpleContentProposalProvider$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/SimpleContentProposalProvider.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/TextContentAdapter.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/fieldassist/TextControlCreator.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/internal/InternalPolicy.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/internal/JFaceActivator.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/BooleanFieldEditor$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/BooleanFieldEditor$2.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/BooleanFieldEditor.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/BooleanPropertyAction$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/BooleanPropertyAction.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/ColorFieldEditor$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/ColorFieldEditor.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/ColorSelector$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/ColorSelector$2.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/ColorSelector$3.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/ColorSelector.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/ComboFieldEditor$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/ComboFieldEditor.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/DirectoryFieldEditor.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/FieldEditor$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/FieldEditor.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/FieldEditorPreferencePage.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/FileFieldEditor.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/FontFieldEditor$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/FontFieldEditor$2.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/FontFieldEditor$3.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/FontFieldEditor$4.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/FontFieldEditor$DefaultPreviewer.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/FontFieldEditor.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/IPersistentPreferenceStore.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/IPreferenceNode.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/IPreferencePage.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/IPreferencePageContainer.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/IPreferenceStore.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/IntegerFieldEditor.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/JFacePreferences.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/ListEditor$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/ListEditor$2.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/ListEditor$3.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/ListEditor.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/PathEditor.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/PreferenceContentProvider.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/PreferenceConverter.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/PreferenceDialog$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/PreferenceDialog$10.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/PreferenceDialog$11.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/PreferenceDialog$12.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/PreferenceDialog$13.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/PreferenceDialog$14.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/PreferenceDialog$15.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/PreferenceDialog$2.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/PreferenceDialog$3.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/PreferenceDialog$4.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/PreferenceDialog$5.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/PreferenceDialog$6.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/PreferenceDialog$7.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/PreferenceDialog$8.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/PreferenceDialog$9.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/PreferenceDialog$PageLayout.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/PreferenceDialog.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/PreferenceLabelProvider.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/PreferenceManager.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/PreferenceNode.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/PreferencePage$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/PreferencePage$2.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/PreferencePage$3.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/PreferencePage$4.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/PreferencePage.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/PreferenceStore$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/PreferenceStore.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/RadioGroupFieldEditor$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/RadioGroupFieldEditor$2.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/RadioGroupFieldEditor.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/ScaleFieldEditor$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/ScaleFieldEditor$2.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/ScaleFieldEditor.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/StringButtonFieldEditor$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/StringButtonFieldEditor$2.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/StringButtonFieldEditor.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/StringFieldEditor$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/StringFieldEditor$2.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/StringFieldEditor$3.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/StringFieldEditor$4.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/preference/StringFieldEditor.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/AbstractListViewer$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/AbstractListViewer.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/AbstractTableViewer$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/AbstractTableViewer$2.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/AbstractTableViewer$3.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/AbstractTableViewer$VirtualManager.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/AbstractTableViewer.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/AbstractTreeViewer$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/AbstractTreeViewer$2.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/AbstractTreeViewer$3.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/AbstractTreeViewer$4.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/AbstractTreeViewer$5.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/AbstractTreeViewer$6.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/AbstractTreeViewer$7.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/AbstractTreeViewer$8.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/AbstractTreeViewer$UpdateItemSafeRunnable.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/AbstractTreeViewer.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/AcceptAllFilter.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ArrayContentProvider.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/BaseLabelProvider$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/BaseLabelProvider.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/CellEditor$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/CellEditor$2.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/CellEditor$3.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/CellEditor$4.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/CellEditor$LayoutData.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/CellEditor.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/CellLabelProvider.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/CellNavigationStrategy.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/CheckStateChangedEvent.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/CheckboxCellEditor.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/CheckboxTableViewer$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/CheckboxTableViewer.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/CheckboxTreeViewer$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/CheckboxTreeViewer.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ColorCellEditor$ColorCellLayout.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ColorCellEditor.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ColumnLabelProvider.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ColumnLayoutData.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ColumnPixelData.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ColumnViewer$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ColumnViewer$2.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ColumnViewer$3.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ColumnViewer.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ColumnViewerEditor$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ColumnViewerEditor$2.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ColumnViewerEditor$3.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ColumnViewerEditor$4.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ColumnViewerEditor.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ColumnViewerEditorActivationEvent.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ColumnViewerEditorActivationListener.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ColumnViewerEditorActivationStrategy$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ColumnViewerEditorActivationStrategy.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ColumnViewerEditorDeactivationEvent.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ColumnViewerToolTipSupport.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ColumnWeightData.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ComboBoxCellEditor$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ComboBoxCellEditor$2.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ComboBoxCellEditor$3.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ComboBoxCellEditor$4.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ComboBoxCellEditor.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ComboViewer.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ContentViewer$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ContentViewer$2.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ContentViewer.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/CustomHashtable$EmptyEnumerator.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/CustomHashtable$HashEnumerator.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/CustomHashtable$HashMapEntry.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/CustomHashtable.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/DecoratingLabelProvider.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/DecorationContext.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/DecorationOverlayIcon.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/DialogCellEditor$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/DialogCellEditor$2.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/DialogCellEditor$3.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/DialogCellEditor$DialogCellLayout.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/DialogCellEditor.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/DoubleClickEvent.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/EditingSupport.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/FocusCellHighlighter.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/FocusCellOwnerDrawHighlighter$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/FocusCellOwnerDrawHighlighter.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/IBaseLabelProvider.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/IBasicPropertyConstants.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ICellEditorListener.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ICellEditorValidator.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ICellModifier.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ICheckStateListener.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ICheckable.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/IColorDecorator.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/IColorProvider.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/IContentProvider.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/IDecoration.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/IDecorationContext.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/IDelayedLabelDecorator.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/IDoubleClickListener.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/IElementComparer.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/IFilter.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/IFontDecorator.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/IFontProvider.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/IInputProvider.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/IInputSelectionProvider.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ILabelDecorator.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ILabelProvider.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ILabelProviderListener.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ILazyContentProvider.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ILazyTreeContentProvider.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ILazyTreePathContentProvider.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ILightweightLabelDecorator.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/IOpenListener.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/IPostSelectionProvider.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ISelection.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ISelectionChangedListener.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ISelectionProvider.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/IStructuredContentProvider.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/IStructuredSelection.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ITableColorProvider.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ITableFontProvider.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ITableLabelProvider.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ITreeContentProvider.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ITreePathContentProvider.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ITreePathLabelProvider.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ITreeSelection.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ITreeViewerListener.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/IViewerLabelProvider.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/LabelDecorator.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/LabelProvider.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/LabelProviderChangedEvent.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ListViewer.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/NamedHandleObjectLabelProvider.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/OpenEvent.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/OwnerDrawLabelProvider$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/OwnerDrawLabelProvider$2.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/OwnerDrawLabelProvider$3.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/OwnerDrawLabelProvider.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/SWTFocusCellManager$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/SWTFocusCellManager$2.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/SWTFocusCellManager$3.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/SWTFocusCellManager.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/SelectionChangedEvent.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/StructuredSelection.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/StructuredViewer$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/StructuredViewer$2.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/StructuredViewer$3.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/StructuredViewer$4.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/StructuredViewer$5.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/StructuredViewer$6.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/StructuredViewer$7.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/StructuredViewer$8.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/StructuredViewer$9.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/StructuredViewer$ColorAndFontCollector.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/StructuredViewer$ColorAndFontCollectorWithProviders.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/StructuredViewer$UpdateItemSafeRunnable.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/StructuredViewer.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/TableColumnViewerLabelProvider.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/TableLayout.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/TableTreeViewer$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/TableTreeViewer$2.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/TableTreeViewer$3.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/TableTreeViewer$4.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/TableTreeViewer$TableTreeEditorImpl.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/TableTreeViewer.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/TableViewer$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/TableViewer.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/TableViewerColumn.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/TableViewerEditor.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/TableViewerFocusCellManager.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/TableViewerRow.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/TextCellEditor$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/TextCellEditor$2.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/TextCellEditor$3.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/TextCellEditor$4.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/TextCellEditor$5.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/TextCellEditor$6.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/TextCellEditor.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/TreeColumnViewerLabelProvider$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/TreeColumnViewerLabelProvider.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/TreeExpansionEvent.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/TreeNode.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/TreeNodeContentProvider.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/TreePath.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/TreePathViewerSorter$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/TreePathViewerSorter.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/TreeSelection$InitializeData.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/TreeSelection.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/TreeViewer$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/TreeViewer$2.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/TreeViewer$3.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/TreeViewer$4.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/TreeViewer$5.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/TreeViewer$6.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/TreeViewer.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/TreeViewerColumn.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/TreeViewerEditor.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/TreeViewerFocusCellManager$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/TreeViewerFocusCellManager.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/TreeViewerRow.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/Viewer$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/Viewer$2.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/Viewer.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ViewerCell.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ViewerColumn$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ViewerColumn$2.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ViewerColumn.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ViewerComparator$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ViewerComparator.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ViewerDropAdapter.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ViewerFilter.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ViewerLabel.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ViewerRow.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/ViewerSorter.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/viewers/WrappedViewerLabelProvider.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/wizard/IWizard.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/wizard/IWizardContainer.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/wizard/IWizardContainer2.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/wizard/IWizardNode.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/wizard/IWizardPage.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/wizard/ProgressMonitorPart$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/wizard/ProgressMonitorPart.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/wizard/Wizard.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/wizard/WizardDialog$1.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/wizard/WizardDialog$2.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/wizard/WizardDialog$3.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/wizard/WizardDialog$4.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/wizard/WizardDialog$5.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/wizard/WizardDialog$6.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/wizard/WizardDialog$PageContainerFillLayout.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/wizard/WizardDialog.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/wizard/WizardPage.class [new file with mode: 0644]
Annotation/src/org/eclipse/jface/wizard/WizardSelectionPage.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/SWT.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/SWTError.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/SWTException.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/XPCOM.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/XPCOMObject.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsDynamicFunctionLoad.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsEmbedString.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIAppShell.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIAuthInformation.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIBaseWindow.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsICancelable.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsICategoryManager.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIChannel.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIClassInfo.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIComponentManager.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIComponentRegistrar.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIContextMenuListener.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsICookie.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsICookieManager.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsICookieService.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsICookieService_1_9.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsID.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIDOMEvent.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIDOMEventTarget.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIDOMKeyEvent.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIDOMMouseEvent.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIDOMSerializer.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIDOMSerializer_1_7.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIDOMUIEvent.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIDOMWindow.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIDOMWindowCollection.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIDataType.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIDirectoryService.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIDirectoryServiceProvider.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIDirectoryServiceProvider2.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIDocShell.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIDocShell_1_8.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIDownload.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIDownload_1_8.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIEmbeddingSiteWindow.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIFactory.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIFile.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIFilePicker.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIFilePicker_1_8.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIHelperAppLauncher.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIHelperAppLauncherDialog.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIHelperAppLauncherDialog_1_9.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIHelperAppLauncher_1_8.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIHelperAppLauncher_1_9.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIIOService.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIInputStream.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIInterfaceRequestor.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIJSContextStack.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsILocalFile.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIMemory.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIObserverService.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIPrefBranch.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIPrefLocalizedString.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIPrefService.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIPrincipal.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIProgressDialog.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIProgressDialog_1_8.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIPromptService.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIPromptService2.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIProperties.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIRequest.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIScriptSecurityManager_1_9.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIScriptSecurityManager_1_9_1.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsISecurityCheckedComponent.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsISerializable.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIServiceManager.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsISimpleEnumerator.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsISupports.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsISupportsWeakReference.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsITooltipListener.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsITransfer.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIURI.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIURIContentListener.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIVariant.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIWeakReference.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIWebBrowser.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIWebBrowserChrome.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIWebBrowserChromeFocus.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIWebBrowserFocus.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIWebBrowserSetup.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIWebBrowserStream.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIWebNavigation.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIWebNavigationInfo.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIWebProgress.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIWebProgressListener.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIWebProgressListener2.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIWindowCreator.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIWindowCreator2.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIWindowWatcher.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIWritableVariant.class [new file with mode: 0644]
Annotation/src/org/eclipse/swt/internal/mozilla/nsIXPCSecurityManager.class [new file with mode: 0644]
Annotation/version.txt [new file with mode: 0644]

diff --git a/Annotation/.classpath b/Annotation/.classpath
new file mode 100644 (file)
index 0000000..156f768
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+       <classpathentry kind="src" path="src"/>
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+       <classpathentry kind="lib" path="/home/lingutln/Downloads/ist-source/Interactive Segmentation App/lib/swt-gtk-64.jar"/>
+       <classpathentry kind="lib" path="/home/lingutln/Downloads/ist-source/Interactive Segmentation App/lib/jface.jar"/>
+       <classpathentry kind="lib" path="/home/lingutln/workspace/image_annotation/lib/json.jar"/>
+       <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/Annotation/.gitignore b/Annotation/.gitignore
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/Annotation/.project b/Annotation/.project
new file mode 100644 (file)
index 0000000..e0f3845
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>Annotation</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.jdt.core.javabuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.jdt.core.javanature</nature>
+       </natures>
+</projectDescription>
diff --git a/Annotation/.settings/org.eclipse.jdt.core.prefs b/Annotation/.settings/org.eclipse.jdt.core.prefs
new file mode 100644 (file)
index 0000000..9e1a043
--- /dev/null
@@ -0,0 +1,12 @@
+#Tue Dec 13 14:02:38 PST 2011
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.6
diff --git a/Annotation/META-INF/ECLIPSE.RSA b/Annotation/META-INF/ECLIPSE.RSA
new file mode 100644 (file)
index 0000000..e370c0e
Binary files /dev/null and b/Annotation/META-INF/ECLIPSE.RSA differ
diff --git a/Annotation/META-INF/ECLIPSE.SF b/Annotation/META-INF/ECLIPSE.SF
new file mode 100644 (file)
index 0000000..662042c
--- /dev/null
@@ -0,0 +1,2219 @@
+Signature-Version: 1.0\r
+SHA1-Digest-Manifest-Main-Attributes: 5EWAvbAiR6Q4Q79WtdyMPP5did0=\r
+Created-By: 1.5.0 (IBM Corporation)\r
+SHA1-Digest-Manifest: 84TjmKKEeQbxGf6FHXw8xH9Wnt4=\r
+\r
+Name: org/eclipse/jface/fieldassist/ControlDecoration$2.class\r
+SHA1-Digest: iGZzlMSQnikJlp+jw0oCR4mBOgE=\r
+\r
+Name: org/eclipse/jface/preference/PreferencePage$3.class\r
+SHA1-Digest: qF1zFYwLQhp4SagSACM13Hj3CbQ=\r
+\r
+Name: org/eclipse/jface/preference/PreferenceDialog$4.class\r
+SHA1-Digest: jTe+5Kj0fw7HBrMorB9wnfwA+aQ=\r
+\r
+Name: org/eclipse/jface/preference/RadioGroupFieldEditor.class\r
+SHA1-Digest: GvdMdbOhtG0PFj1BCRskOj/mncc=\r
+\r
+Name: org/eclipse/jface/dialogs/Dialog.class\r
+SHA1-Digest: zG6Ozv8VWfsFI7UDzB8XlSeEUFM=\r
+\r
+Name: org/eclipse/jface/internal/JFaceActivator.class\r
+SHA1-Digest: uCLmH9z+xLKaGimc/A2D34kztrI=\r
+\r
+Name: org/eclipse/jface/bindings/CachedBindingSet.class\r
+SHA1-Digest: 7rqIEDyVwUfjsGZBymbuHjpcuZ0=\r
+\r
+Name: org/eclipse/jface/viewers/ViewerRow.class\r
+SHA1-Digest: 8qoYH649iJt30GFqXWgvxGgPxVI=\r
+\r
+Name: org/eclipse/jface/fieldassist/IContentProposalListener.class\r
+SHA1-Digest: tmRtj73sYnqzleK2xxiOyzE1L1k=\r
+\r
+Name: org/eclipse/jface/operation/AccumulatingProgressMonitor$4.class\r
+SHA1-Digest: m2DvMWv0btAAjBlhol5Yyyi1Hjw=\r
+\r
+Name: org/eclipse/jface/viewers/ICellModifier.class\r
+SHA1-Digest: MLWSDSBJALcKVtHybMcxQvrkiuw=\r
+\r
+Name: org/eclipse/jface/dialogs/DialogPage.class\r
+SHA1-Digest: paRcOAFkjDH7SYEVfeqMKqVKJa0=\r
+\r
+Name: org/eclipse/jface/dialogs/ProgressMonitorDialog.class\r
+SHA1-Digest: +EdvdkPTMVBPM4ecBxhkEZrKqtk=\r
+\r
+Name: org/eclipse/jface/action/AbstractAction.class\r
+SHA1-Digest: w0kJoNREzOzn43LG2L5iaFwnaPc=\r
+\r
+Name: org/eclipse/jface/viewers/StructuredViewer$ColorAndFontCollector\r
+ .class\r
+SHA1-Digest: K/6GSuix21oodCJuGwUG6ztcofw=\r
+\r
+Name: org/eclipse/jface/dialogs/IconAndMessageDialog.class\r
+SHA1-Digest: nYuOeO2gOZtFkL31QpAAvvBrjVI=\r
+\r
+Name: org/eclipse/jface/fieldassist/SimpleContentProposalProvider$1.cl\r
+ ass\r
+SHA1-Digest: nxcSSDXMNp3hYPYbERVhhXDSfwU=\r
+\r
+Name: org/eclipse/jface/dialogs/DialogMessageArea.class\r
+SHA1-Digest: 0pmQEGMPsY/H9zdgGsE/LdE0qKs=\r
+\r
+Name: org/eclipse/jface/operation/IRunnableContext.class\r
+SHA1-Digest: /EcDpCNiCk6CuDPOVJ9/VLxELxI=\r
+\r
+Name: org/eclipse/jface/viewers/AbstractTreeViewer$4.class\r
+SHA1-Digest: 0tpIkrdSqJGGtf6gLpvs5mixjoI=\r
+\r
+Name: org/eclipse/jface/dialogs/MessageDialogWithToggle.class\r
+SHA1-Digest: Pc562HrcnM8tamv1cFpR2t/4AK4=\r
+\r
+Name: org/eclipse/jface/viewers/Viewer$2.class\r
+SHA1-Digest: Cx2F7HkRfJfkgTCmv3fya0SJgD0=\r
+\r
+Name: org/eclipse/jface/action/ActionContributionItem$5.class\r
+SHA1-Digest: jMg3zDTLAxesrNizIY+xdwPv8Wg=\r
+\r
+Name: org/eclipse/jface/viewers/ColumnViewerEditorActivationStrategy.c\r
+ lass\r
+SHA1-Digest: 7jzZvzV76INEtLejjrRF0KpFMJI=\r
+\r
+Name: org/eclipse/jface/viewers/TreeViewerEditor.class\r
+SHA1-Digest: 7L/k0DP2bSjtrQIQo+KgChSJML8=\r
+\r
+Name: org/eclipse/jface/bindings/keys/IKeyLookup.class\r
+SHA1-Digest: 3RO+TXrY+GUrNbqfPdXdS/umgF8=\r
+\r
+Name: org/eclipse/jface/viewers/TableViewerEditor.class\r
+SHA1-Digest: YOBbpDpgWafz8nz4AFar85A7xoI=\r
+\r
+Name: org/eclipse/jface/viewers/AbstractTableViewer$1.class\r
+SHA1-Digest: 90MbjrI3u2AXcS3vs2ztUNUlp9g=\r
+\r
+Name: org/eclipse/jface/viewers/StructuredViewer$8.class\r
+SHA1-Digest: 36SQLLvrPr8LTXtO4/9+mFaI1vc=\r
+\r
+Name: org/eclipse/jface/fieldassist/ComboContentAdapter.class\r
+SHA1-Digest: QRz+sVte5Ms73iIHkFfgsWy1i3Y=\r
+\r
+Name: org/eclipse/jface/action/IStatusLineManager.class\r
+SHA1-Digest: a4GdvF+6pe+bbvRc6QJRyUaQoLk=\r
+\r
+Name: org/eclipse/jface/window/IShellProvider.class\r
+SHA1-Digest: YLuzbe/8n6jGYsAGro9+z7HrwGU=\r
+\r
+Name: org/eclipse/jface/viewers/ListViewer.class\r
+SHA1-Digest: DKR66oVPaOLKJJOAIrM6Z7z+Ajo=\r
+\r
+Name: org/eclipse/jface/fieldassist/ContentProposalAdapter$1.class\r
+SHA1-Digest: 0gy1qbGJIfonNbxdi/D6T+7RPEQ=\r
+\r
+Name: org/eclipse/jface/viewers/ILazyTreeContentProvider.class\r
+SHA1-Digest: qWN0XG4Qhia6KvxFLrIPK/eVfEE=\r
+\r
+Name: org/eclipse/jface/viewers/TextCellEditor$4.class\r
+SHA1-Digest: QgEz4CI4aGL5ZykOCKFuE28CDu0=\r
+\r
+Name: org/eclipse/jface/bindings/keys/KeySequenceText$KeyTrapListener.\r
+ class\r
+SHA1-Digest: 0N7egGc+uYroh6YoN8QtX3UG1oA=\r
+\r
+Name: org/eclipse/jface/preference/PreferenceLabelProvider.class\r
+SHA1-Digest: 89CKBoan2dnwFULZWROtmX+0Cpk=\r
+\r
+Name: org/eclipse/jface/action/ToolBarContributionItem$4.class\r
+SHA1-Digest: GBm74NJU+trWLBjMR5mvo386ymA=\r
+\r
+Name: org/eclipse/jface/bindings/SchemeEvent.class\r
+SHA1-Digest: hoZW87aPwR8U0YvqYaZI9HMu6C8=\r
+\r
+Name: org/eclipse/jface/commands/PersistentState.class\r
+SHA1-Digest: yL3lMIitYZ+ms6h0zAmyB6SZCFk=\r
+\r
+Name: org/eclipse/jface/viewers/IBasicPropertyConstants.class\r
+SHA1-Digest: lIP3Ni4M1fUH5CwarS0KMtioceg=\r
+\r
+Name: org/eclipse/jface/fieldassist/ContentProposalAdapter.class\r
+SHA1-Digest: rA1DcSYjmxcedjABiaEKospSAto=\r
+\r
+Name: org/eclipse/jface/action/ExternalActionManager.properties\r
+SHA1-Digest: UueIvQ/nF9uuYBwcs1azcYU19uc=\r
+\r
+Name: org/eclipse/jface/preference/BooleanFieldEditor$1.class\r
+SHA1-Digest: 5kEPR9EotiV4X1c6jMjI0oqK/Ns=\r
+\r
+Name: org/eclipse/jface/dialogs/ProgressMonitorDialog$3.class\r
+SHA1-Digest: PyFbLevAtCrXakbSmqpXhcWajzM=\r
+\r
+Name: org/eclipse/jface/resource/ImageDescriptor.class\r
+SHA1-Digest: WzgmcUKovAQ9VO4qE9zDbzxTpOk=\r
+\r
+Name: org/eclipse/jface/viewers/deferred/DeferredContentProvider.class\r
+SHA1-Digest: 9Wk50rmWV3ImvRvXRG58iffbx+4=\r
+\r
+Name: org/eclipse/jface/window/Window$3.class\r
+SHA1-Digest: qtonjTRSx2Lt3CMTj6DbJbaLnbA=\r
+\r
+Name: org/eclipse/jface/viewers/CustomHashtable$HashMapEntry.class\r
+SHA1-Digest: tPgEFUQac0g46rfQBPdpf0vMVTU=\r
+\r
+Name: org/eclipse/jface/viewers/ContentViewer.class\r
+SHA1-Digest: XRPy4VxsQalW4K3gTLZ0C/AZvCs=\r
+\r
+Name: org/eclipse/jface/viewers/IFontProvider.class\r
+SHA1-Digest: g/dCUHHOCwC1gWJnqYVUuOkbLWE=\r
+\r
+Name: org/eclipse/jface/preference/IPersistentPreferenceStore.class\r
+SHA1-Digest: 0h/VCibXYY6f837VN8gZHYVC9AY=\r
+\r
+Name: org/eclipse/jface/viewers/ISelectionChangedListener.class\r
+SHA1-Digest: zsv0sq11yrTP//btCXjMitoyTUg=\r
+\r
+Name: org/eclipse/jface/viewers/CheckboxTreeViewer.class\r
+SHA1-Digest: 2IuKVo0W0eefa1r+aXz1h54zCAQ=\r
+\r
+Name: org/eclipse/jface/operation/IRunnableWithProgress.class\r
+SHA1-Digest: pU3FXK0vb68suXDN0vVqFRsVi0U=\r
+\r
+Name: org/eclipse/jface/bindings/keys/formatting/AbstractKeyFormatter.\r
+ properties\r
+SHA1-Digest: qQ7mPHSVsC3AQZDzY6RmQ1DfwiA=\r
+\r
+Name: org/eclipse/jface/viewers/DecoratingLabelProvider.class\r
+SHA1-Digest: vcnZjCwHH8uRYDf3nDQXm04+ZwI=\r
+\r
+Name: org/eclipse/jface/resource/FontRegistry$FontRecord.class\r
+SHA1-Digest: 1eBoKicV0hgzRjOxO3Rx/ebUozg=\r
+\r
+Name: org/eclipse/jface/window/ToolTip$4.class\r
+SHA1-Digest: CGbQ81V61G+73ENinJAskhr2jlY=\r
+\r
+Name: org/eclipse/jface/viewers/deferred/SetModel.class\r
+SHA1-Digest: h5lrw51Xq5crMZMvRi6MWgsl76M=\r
+\r
+Name: org/eclipse/jface/viewers/ITableFontProvider.class\r
+SHA1-Digest: PXD0wkY3N2bk3rpL6+CIMOu+dec=\r
+\r
+Name: org/eclipse/jface/preference/FieldEditor.class\r
+SHA1-Digest: 7K4g+fddHzmlVs8G2DpfW6RY5Xg=\r
+\r
+Name: org/eclipse/jface/preference/StringFieldEditor$4.class\r
+SHA1-Digest: 1n/UsXplUufL9Rt1kw8uJQOkvqE=\r
+\r
+Name: org/eclipse/jface/wizard/IWizard.class\r
+SHA1-Digest: OpJzFa5/5cY1FZmwhojIvRpb15Y=\r
+\r
+Name: org/eclipse/jface/viewers/TreeViewer$6.class\r
+SHA1-Digest: oYD52jDXsjqz7sYPpI+g19uH2ws=\r
+\r
+Name: org/eclipse/jface/fieldassist/AutoCompleteField.class\r
+SHA1-Digest: 3N38AL22/8ZgQEatQpXjm3ZsMps=\r
+\r
+Name: org/eclipse/jface/action/Separator.class\r
+SHA1-Digest: UvxUEudgExshA7J7wb5BoFESz0g=\r
+\r
+Name: org/eclipse/jface/resource/ColorRegistry$1.class\r
+SHA1-Digest: f71p6xN807Y6b/y2nqF5gmzazBY=\r
+\r
+Name: org/eclipse/jface/bindings/keys/formatting/AbstractKeyFormatter.\r
+ class\r
+SHA1-Digest: JijjWGplCRMUfslb2x2ncB9+6Pw=\r
+\r
+Name: org/eclipse/jface/preference/FontFieldEditor.class\r
+SHA1-Digest: mEDoY6sUprGzmhKjO1dniSDCa10=\r
+\r
+Name: org/eclipse/jface/window/ApplicationWindow.class\r
+SHA1-Digest: IZl1iLxQgeG+UAsoLbsEQM8RSxw=\r
+\r
+Name: org/eclipse/jface/viewers/StructuredViewer$3.class\r
+SHA1-Digest: VQYLNVmwiILmm++iCDrzx+LWZEo=\r
+\r
+Name: org/eclipse/jface/util/DelegatingDropAdapter$2.class\r
+SHA1-Digest: heTOuGjccnCCplk8AqdiPQYklD8=\r
+\r
+Name: org/eclipse/jface/fieldassist/ControlDecoration$8.class\r
+SHA1-Digest: jI6Z36lYy2QgSdrlOR2sxyJNSNc=\r
+\r
+Name: org/eclipse/jface/fieldassist/DecoratedField$4.class\r
+SHA1-Digest: iADBpnr8VrqHDJKTsSHkacaBMC8=\r
+\r
+Name: org/eclipse/jface/fieldassist/ContentProposalAdapter$10.class\r
+SHA1-Digest: FAxocK04ZrFWJFeAMtCAs+9CRJo=\r
+\r
+Name: org/eclipse/jface/preference/RadioGroupFieldEditor$2.class\r
+SHA1-Digest: AJVgCJqIuJFv2xiltX4vRp4VoQY=\r
+\r
+Name: org/eclipse/jface/resource/AbstractResourceManager.class\r
+SHA1-Digest: KknrjuPVMJyKGhIyeALK1NhGbKo=\r
+\r
+Name: org/eclipse/jface/action/StatusLineManager$1.class\r
+SHA1-Digest: jE5hBsg9R+QrrP3IIr2ZZ10Ug9A=\r
+\r
+Name: org/eclipse/jface/preference/ColorSelector$1.class\r
+SHA1-Digest: bMvVHd/a7h/77azt3YgqdnCYsPU=\r
+\r
+Name: org/eclipse/jface/viewers/deferred/BackgroundContentProvider.cla\r
+ ss\r
+SHA1-Digest: 5roAVac/frvjMj67eyWqhEIKEIU=\r
+\r
+Name: org/eclipse/jface/action/StatusLine$2.class\r
+SHA1-Digest: G+r8KY3LMsnDaqaKfhWAmSJ+9Qg=\r
+\r
+Name: org/eclipse/jface/dialogs/MessageDialog.class\r
+SHA1-Digest: N374r8GdoJv197GWY9mqNH5eJwA=\r
+\r
+Name: org/eclipse/jface/dialogs/IDialogBlockedHandler.class\r
+SHA1-Digest: tKloZ49QXCFTDoMfu1Vb2+MxJtQ=\r
+\r
+Name: org/eclipse/jface/wizard/WizardDialog$6.class\r
+SHA1-Digest: GqUX7gcsWOQaipxTsfDEuylDye8=\r
+\r
+Name: org/eclipse/jface/viewers/deferred/AbstractVirtualTable.class\r
+SHA1-Digest: brnlUiB6TTYrfbSsYrcFQkdnv7Y=\r
+\r
+Name: org/eclipse/jface/viewers/IFontDecorator.class\r
+SHA1-Digest: 891zp1j09NBrzqwkKlmW6pm/1+U=\r
+\r
+Name: org/eclipse/jface/preference/PreferenceDialog$15.class\r
+SHA1-Digest: wTJzQ/mvWex9xus+cCxH5esrbhs=\r
+\r
+Name: org/eclipse/jface/viewers/deferred/AbstractConcurrentModel.class\r
+SHA1-Digest: Pl29R9jkzZNC/ahl5xDa1TrFOEE=\r
+\r
+Name: org/eclipse/jface/viewers/SelectionChangedEvent.class\r
+SHA1-Digest: D0XjDa8cFH1VCo6lbeTMx/FQkws=\r
+\r
+Name: org/eclipse/jface/viewers/CheckboxTreeViewer$1.class\r
+SHA1-Digest: TNNQiMqPUJud17cCPA2IEFcw+Og=\r
+\r
+Name: org/eclipse/jface/wizard/WizardSelectionPage.class\r
+SHA1-Digest: uE3H+08Tiu1/bqHwyx2gXgfWe3o=\r
+\r
+Name: org/eclipse/jface/viewers/SWTFocusCellManager$1.class\r
+SHA1-Digest: JwDhPhtCJhYEkzul0sQa0iCjwqg=\r
+\r
+Name: org/eclipse/jface/dialogs/PopupDialog$5.class\r
+SHA1-Digest: IGv9QPtbXGBGrCFLlICFjvhF6uI=\r
+\r
+Name: org/eclipse/jface/fieldassist/ControlDecoration.class\r
+SHA1-Digest: Wymg79Vuh3R2r18c3reOJiOzNto=\r
+\r
+Name: org/eclipse/jface/viewers/ComboBoxCellEditor$4.class\r
+SHA1-Digest: 2Mv9grE6uGu+MLdLZaUPzTXHf8A=\r
+\r
+Name: org/eclipse/jface/viewers/OwnerDrawLabelProvider$2.class\r
+SHA1-Digest: SpYWw9tEhqwiWSOsnDNqB2mrb3E=\r
+\r
+Name: org/eclipse/jface/resource/FontDescriptor.class\r
+SHA1-Digest: eT5gH5T1mgfxlTl/DeD9o/+2xcQ=\r
+\r
+Name: org/eclipse/jface/preference/PreferencePage.class\r
+SHA1-Digest: fkGGQdxuSvXQhwO/6nTr4s2pFSs=\r
+\r
+Name: org/eclipse/jface/util/PropertyChangeEvent.class\r
+SHA1-Digest: EajgzipEUA6FJYIyyR8HlDUaJuU=\r
+\r
+Name: org/eclipse/jface/fieldassist/DecoratedField$Hover.class\r
+SHA1-Digest: CwXHp+oid5QN8CC/agHhYygRu/0=\r
+\r
+Name: org/eclipse/jface/dialogs/PageChangingEvent.class\r
+SHA1-Digest: EzH4BwyIhpqgE4NpiDdYb77D2RI=\r
+\r
+Name: org/eclipse/jface/viewers/IDecorationContext.class\r
+SHA1-Digest: uo0idfey67ODyrk3PuQe0JBR1Co=\r
+\r
+Name: org/eclipse/jface/viewers/deferred/ConcurrentTableUpdator$1.clas\r
+ s\r
+SHA1-Digest: D4I8+a7OEFF+9scpYvL8fPNE35U=\r
+\r
+Name: org/eclipse/jface/wizard/WizardDialog.class\r
+SHA1-Digest: j3QiBHFGoqNYM9lYRlKjJACLmxo=\r
+\r
+Name: org/eclipse/jface/viewers/IInputProvider.class\r
+SHA1-Digest: +4gWEOSXC6MMfxwKnaxLWuHxC+c=\r
+\r
+Name: org/eclipse/jface/fieldassist/IContentProposalProvider.class\r
+SHA1-Digest: Me8Rz5jWeHYl8X6CEASTGEOjXng=\r
+\r
+Name: org/eclipse/jface/window/SameShellProvider.class\r
+SHA1-Digest: D+ZZxaND3T79NvHygMhumBnTezU=\r
+\r
+Name: org/eclipse/jface/action/IContributionManagerOverrides.class\r
+SHA1-Digest: XT0XSk1MLNZgd1GM64ODnBmwKeM=\r
+\r
+Name: org/eclipse/jface/util/DelegatingDragAdapter$1.class\r
+SHA1-Digest: 9fux831/DeidfEcSTMrOkGOicBU=\r
+\r
+Name: org/eclipse/jface/window/Window.class\r
+SHA1-Digest: f2LgB6JO8pAE3znhtDOhHtOsPbU=\r
+\r
+Name: org/eclipse/jface/fieldassist/IControlContentAdapter.class\r
+SHA1-Digest: X56J3Fu2l9LAmCgRSEygaTm/E2Q=\r
+\r
+Name: org/eclipse/jface/util/Policy$1.class\r
+SHA1-Digest: FdI6d9oWZD67J54iUPVuU07nlyE=\r
+\r
+Name: org/eclipse/jface/viewers/ColumnPixelData.class\r
+SHA1-Digest: 3hM93QKuNRIeZy7kMUSzW3G2bjc=\r
+\r
+Name: org/eclipse/jface/bindings/keys/formatting/FormalKeyFormatter.cl\r
+ ass\r
+SHA1-Digest: NLAxKJ3zlljxjxs4Qtf1U1JEaEg=\r
+\r
+Name: org/eclipse/jface/resource/jfacefonts_hp-ux.properties\r
+SHA1-Digest: DdgNeYu/6JwIhnA+ziuY1MfdoMY=\r
+\r
+Name: org/eclipse/jface/window/ApplicationWindow$1.class\r
+SHA1-Digest: pZkzltYH/pT7NJT6JoBaOLA2e/w=\r
+\r
+Name: org/eclipse/jface/viewers/TreeViewer$1.class\r
+SHA1-Digest: vDSjOG6fISzrQOq+81/A0NXaeak=\r
+\r
+Name: org/eclipse/jface/bindings/keys/KeySequenceText$1.class\r
+SHA1-Digest: T7wVfH1jsrxsAwFuDwOw2VujKuI=\r
+\r
+Name: org/eclipse/jface/fieldassist/FieldDecoration.class\r
+SHA1-Digest: yxaNFae07DcPFqt2cS9kkPgyQgE=\r
+\r
+Name: org/eclipse/jface/resource/URLImageDescriptor.class\r
+SHA1-Digest: xfpFtZYPkTeIkKwUPH7bVYuI0eE=\r
+\r
+Name: org/eclipse/jface/bindings/Binding.class\r
+SHA1-Digest: qUbUSRqzW5b60ay9Stc2r0XhA8E=\r
+\r
+Name: org/eclipse/jface/util/OpenStrategy$4.class\r
+SHA1-Digest: Q34pdgB010llEvChdiVxC7HRZmc=\r
+\r
+Name: org/eclipse/jface/fieldassist/ContentProposalAdapter$7.class\r
+SHA1-Digest: i7tNTnZWospqj0NsfD+Cb3O1nvM=\r
+\r
+Name: org/eclipse/jface/viewers/ColumnViewerEditor.class\r
+SHA1-Digest: qT62vM+iZ793659vi43YypCpRjI=\r
+\r
+Name: org/eclipse/jface/preference/ColorFieldEditor.class\r
+SHA1-Digest: mPMTPU8DZsIHQTfCRx8M2ghvs7s=\r
+\r
+Name: org/eclipse/jface/action/IToolBarManager.class\r
+SHA1-Digest: i+c+nu4vep+zBSrZuORi3Sc/b8o=\r
+\r
+Name: org/eclipse/jface/dialogs/DialogTray.class\r
+SHA1-Digest: 5jxPOwxsY0mRt7x6q1ADmpQ5tk4=\r
+\r
+Name: org/eclipse/jface/bindings/ISchemeListener.class\r
+SHA1-Digest: MMWaPQ7IW9t4niSnqpOqkk2J2ug=\r
+\r
+Name: org/eclipse/jface/resource/ColorRegistry.class\r
+SHA1-Digest: ghlErnokdMnUppnC5Rg64UspcYk=\r
+\r
+Name: org/eclipse/jface/layout/TreeColumnLayout$TreeLayoutListener.cla\r
+ ss\r
+SHA1-Digest: 70Vw7oLYGelbGNaXCxT7JoAp7ko=\r
+\r
+Name: org/eclipse/jface/viewers/BaseLabelProvider$1.class\r
+SHA1-Digest: VJ0cyhBjSbI1mJUv63hSalGJKYQ=\r
+\r
+Name: org/eclipse/jface/fieldassist/ControlDecoration$3.class\r
+SHA1-Digest: Mm3k4+hXRB2D0n0mMc8FLM0MebE=\r
+\r
+Name: org/eclipse/jface/viewers/IColorProvider.class\r
+SHA1-Digest: 8DcdSk9zjqjd/JtQUfu3j6/h/gQ=\r
+\r
+Name: org/eclipse/jface/preference/PreferencePage$4.class\r
+SHA1-Digest: lknbKDfMDxyQskxfxKKxN1GCJ9Q=\r
+\r
+Name: org/eclipse/jface/resource/ImageRegistry.class\r
+SHA1-Digest: 8gXTaXNH5orPlV5rTOOg7MzXXR0=\r
+\r
+Name: org/eclipse/jface/viewers/ViewerColumn.class\r
+SHA1-Digest: e2VIRAB1IO+iCFTJEchSoiz3XF8=\r
+\r
+Name: org/eclipse/jface/viewers/ViewerComparator.class\r
+SHA1-Digest: EBmM3EbHDfVZThgHARGD4cT6Wyw=\r
+\r
+Name: org/eclipse/jface/action/ToolBarManager.class\r
+SHA1-Digest: C7ImvSN0ik3hKhB/r6tWPjEtdrg=\r
+\r
+Name: org/eclipse/jface/viewers/deferred/IConcurrentModel.class\r
+SHA1-Digest: FNQSCi9PiBLCYeAzDohidY6sP5w=\r
+\r
+Name: org/eclipse/jface/action/IContributionItem.class\r
+SHA1-Digest: bXDHmVshoXP39HMPjpqJz0NuwK8=\r
+\r
+Name: org/eclipse/jface/preference/PreferenceDialog$5.class\r
+SHA1-Digest: 4JsPFuoXAugqDDTWI5r5en2z3hY=\r
+\r
+Name: org/eclipse/jface/internal/provisional/action/ToolBarManager2.cl\r
+ ass\r
+SHA1-Digest: 5+YgtcblKrsWfrixChkGIYI9VUg=\r
+\r
+Name: org/eclipse/jface/viewers/BaseLabelProvider.class\r
+SHA1-Digest: /5bVcq79HIp/BwtP46v/pFMPIhk=\r
+\r
+Name: org/eclipse/jface/wizard/WizardDialog$1.class\r
+SHA1-Digest: IvzKz6Xl699zp2RS/tAJDVRgWgE=\r
+\r
+Name: org/eclipse/jface/preference/PreferenceDialog$10.class\r
+SHA1-Digest: Bg2Kn2uLL08EWFb+4HAimWZkOzc=\r
+\r
+Name: org/eclipse/jface/viewers/ITreePathLabelProvider.class\r
+SHA1-Digest: 8Nb2jUmFJW0Jn+LeSAYeweeo2Ew=\r
+\r
+Name: org/eclipse/jface/viewers/LabelProviderChangedEvent.class\r
+SHA1-Digest: mbQZ/j6whMi4RcB8mjBveK7zcTE=\r
+\r
+Name: org/eclipse/jface/action/ToolBarContributionItem.class\r
+SHA1-Digest: C9BtCUPurPzQewoeYCwFDrdZGR8=\r
+\r
+Name: org/eclipse/jface/action/LegacyActionTools.class\r
+SHA1-Digest: P57JOvtufqnWZsMqVEdHjcNEwxo=\r
+\r
+Name: org/eclipse/jface/operation/AccumulatingProgressMonitor$5.class\r
+SHA1-Digest: GKMNPGNT2UZQRMo09apctBBvFpo=\r
+\r
+Name: org/eclipse/jface/viewers/SWTFocusCellManager.class\r
+SHA1-Digest: MP6fa7q73TKIJX8Uv7BSUp4qIqE=\r
+\r
+Name: org/eclipse/jface/viewers/OwnerDrawLabelProvider.class\r
+SHA1-Digest: kbzmkO9H7tDizrX1aAszpA/Wj3U=\r
+\r
+Name: org/eclipse/jface/action/SubToolBarManager.class\r
+SHA1-Digest: e15sVyMVIa81F9VydWgI+l7fPqs=\r
+\r
+Name: org/eclipse/jface/viewers/ColumnLayoutData.class\r
+SHA1-Digest: wR/4YK+DCcWF+TqH+EPnfEnI6lI=\r
+\r
+Name: org/eclipse/jface/util/ISafeRunnableRunner.class\r
+SHA1-Digest: C4a7MwkgoLP1QXl3fkLZXbIjYqM=\r
+\r
+Name: org/eclipse/jface/util/TransferDropTargetListener.class\r
+SHA1-Digest: 6FZoSxMHKoPfstPic/1GMQlktc8=\r
+\r
+Name: org/eclipse/jface/fieldassist/FieldDecorationRegistry$Entry.clas\r
+ s\r
+SHA1-Digest: xruXtxS3oTQD7qVLiZjFbWq4Kzc=\r
+\r
+Name: org/eclipse/jface/viewers/DialogCellEditor$1.class\r
+SHA1-Digest: wiz/rzkV2RcqrTYLiYroFTHf5xo=\r
+\r
+Name: org/eclipse/jface/viewers/AbstractTreeViewer$5.class\r
+SHA1-Digest: zaDihpPtfDGrwSrbdPwpW4EPw/A=\r
+\r
+Name: org/eclipse/jface/viewers/DoubleClickEvent.class\r
+SHA1-Digest: aYLfn0r6mq8YUfky0Iom6C4mg5E=\r
+\r
+Name: org/eclipse/jface/fieldassist/IContentProposal.class\r
+SHA1-Digest: odEBYrDVhWgkCWdC1ABLvXBBl+o=\r
+\r
+Name: org/eclipse/jface/action/ActionContributionItem$6.class\r
+SHA1-Digest: UsE4FYilN88afT9IkOsK71pY8CY=\r
+\r
+Name: org/eclipse/jface/viewers/AbstractListViewer$1.class\r
+SHA1-Digest: UEQ3dWFrwQJ56Q6bXMzvgGxMKI8=\r
+\r
+Name: org/eclipse/jface/bindings/keys/KeyLookupFactory.class\r
+SHA1-Digest: +XqDeX8VBAEJp53sdpg4E9sKmUA=\r
+\r
+Name: org/eclipse/jface/viewers/AbstractTableViewer$2.class\r
+SHA1-Digest: Vi0qeWuO/PIJKNe2PuAI7xH9wso=\r
+\r
+Name: org/eclipse/jface/action/IMenuCreator.class\r
+SHA1-Digest: kieVrrSWjOqN28wXYLHKDjzOg90=\r
+\r
+Name: org/eclipse/jface/viewers/TableTreeViewer$1.class\r
+SHA1-Digest: f6aAKLuJn0bhKCMDJDTBNOIodrg=\r
+\r
+Name: org/eclipse/jface/viewers/StructuredViewer$9.class\r
+SHA1-Digest: ClRZsrmpOwGpCvwAubTFNfpFmkI=\r
+\r
+Name: org/eclipse/jface/menus/AbstractTrimWidget.class\r
+SHA1-Digest: /fEqZ6WMBxIOHILszWWszkZtcmw=\r
+\r
+Name: org/eclipse/jface/viewers/ViewerCell.class\r
+SHA1-Digest: XvPDw5i/CSGXMM3hV4j+yv9Qwpo=\r
+\r
+Name: org/eclipse/jface/viewers/AbstractListViewer.class\r
+SHA1-Digest: VEzvbObT+6LuhCaQ6hBgF852BTc=\r
+\r
+Name: org/eclipse/jface/fieldassist/ContentProposalAdapter$2.class\r
+SHA1-Digest: +7+8Z9qHzaXfVjLdbWC0qrUpyBg=\r
+\r
+Name: org/eclipse/jface/viewers/ComboViewer.class\r
+SHA1-Digest: 9fR3KEGUr2OiW2h7zHb1DBj6Pco=\r
+\r
+Name: org/eclipse/jface/viewers/TextCellEditor$5.class\r
+SHA1-Digest: eHLnVLxCl8i6msLemooRW7oJ4xM=\r
+\r
+Name: org/eclipse/jface/wizard/Wizard.class\r
+SHA1-Digest: LazrshzZld3IMGIrmlX/hH/uF40=\r
+\r
+Name: org/eclipse/jface/dialogs/InputDialog.class\r
+SHA1-Digest: Fp0WtGtRPp/9AJRVFAyCO81KR/M=\r
+\r
+Name: org/eclipse/jface/viewers/IInputSelectionProvider.class\r
+SHA1-Digest: MZI5TJ9X1919Jkk8lkgpbEX8dc0=\r
+\r
+Name: org/eclipse/jface/resource/FontRegistry.class\r
+SHA1-Digest: xB+IDR83HvKXJStlHG87e6rR16s=\r
+\r
+Name: org/eclipse/jface/viewers/TreeViewerColumn.class\r
+SHA1-Digest: Yc6eUSCm/cmfBsMAYumBRUv9j84=\r
+\r
+Name: org/eclipse/jface/action/ExternalActionManager.class\r
+SHA1-Digest: cPFGv9W+qowqdUdaA4MmCLfmxU8=\r
+\r
+Name: org/eclipse/jface/action/ICoolBarManager.class\r
+SHA1-Digest: SsIS4rnUWyYkuY2nOs5l5rXr3EU=\r
+\r
+Name: org/eclipse/jface/viewers/TableViewerColumn.class\r
+SHA1-Digest: 2qd3dEc1q04dyEowPw624ZvF97M=\r
+\r
+Name: org/eclipse/jface/dialogs/DialogSettings.class\r
+SHA1-Digest: 79eryhvFMtUJ5lgxebp1v4QHZZ0=\r
+\r
+Name: org/eclipse/jface/resource/AbstractResourceManager$RefCount.clas\r
+ s\r
+SHA1-Digest: LiZU6gMUXyxQDMWWqn2tny7XAcY=\r
+\r
+Name: org/eclipse/jface/preference/ColorSelector.class\r
+SHA1-Digest: vYzAt0XEUxYV4isQaBFxiD0C9V8=\r
+\r
+Name: org/eclipse/jface/action/StatusLineManager.class\r
+SHA1-Digest: yVxa+rR0vV8a2p76wuu5dkubmb8=\r
+\r
+Name: org/eclipse/jface/preference/BooleanFieldEditor$2.class\r
+SHA1-Digest: KGKiEM5qjLC/kMYRuS3RyNHefqQ=\r
+\r
+Name: org/eclipse/jface/viewers/ViewerSorter.class\r
+SHA1-Digest: 8h50w1p2p1PFPmPdMc3iosjcJ0Y=\r
+\r
+Name: org/eclipse/jface/dialogs/ProgressIndicator.class\r
+SHA1-Digest: rGsMOj7x4nT9+UE/z04O4hKA/8k=\r
+\r
+Name: org/eclipse/jface/viewers/TreeColumnViewerLabelProvider$1.class\r
+SHA1-Digest: LayPvFXQFPFIOB72JEhVJ5/J/Oo=\r
+\r
+Name: org/eclipse/jface/window/ApplicationWindow$ApplicationWindowLayo\r
+ ut.class\r
+SHA1-Digest: DYR+N03EEHLYLAgKosledVrh1vI=\r
+\r
+Name: org/eclipse/jface/action/CoolBarManager.class\r
+SHA1-Digest: QEzBDIxP6BXcPEKKSr1Iy/gxtNo=\r
+\r
+Name: org/eclipse/jface/fieldassist/FieldDecorationRegistry.class\r
+SHA1-Digest: Gqr8/Y9YF7qdXEnEypAjd18XsLI=\r
+\r
+Name: org/eclipse/jface/viewers/IOpenListener.class\r
+SHA1-Digest: LkdnUxquMcFT9cE12C0Rr39PLwQ=\r
+\r
+Name: org/eclipse/jface/preference/FieldEditor$1.class\r
+SHA1-Digest: ncOEYR67CeB+YDPHOVDFLEGaDPc=\r
+\r
+Name: org/eclipse/jface/preference/IPreferencePage.class\r
+SHA1-Digest: rNfcBt1JT6gR3RHOc82WxhjhQNA=\r
+\r
+Name: org/eclipse/jface/preference/BooleanFieldEditor.class\r
+SHA1-Digest: tI75Elc7BcBxkahHXb0fmkfVqvw=\r
+\r
+Name: org/eclipse/jface/viewers/ITableLabelProvider.class\r
+SHA1-Digest: k/fkWmJL0Z/pbnEjoHXtK9xxSZU=\r
+\r
+Name: org/eclipse/jface/util/SafeRunnableDialog$1.class\r
+SHA1-Digest: gRS/fSnSA8k1VgfqJ6p3s1u2kWY=\r
+\r
+Name: org/eclipse/jface/layout/AbstractColumnLayout.class\r
+SHA1-Digest: f/ByQWIeY0o9i77B9xmCP9XdG/o=\r
+\r
+Name: org/eclipse/jface/viewers/StructuredViewer$ColorAndFontCollector\r
+ WithProviders.class\r
+SHA1-Digest: 0lcbRO1FqTxlPOYp4r5CQKwzubU=\r
+\r
+Name: org/eclipse/jface/internal/provisional/action/IToolBarManager2.c\r
+ lass\r
+SHA1-Digest: kXWlyfzHabQlbfj+HnZ/5hfXqK8=\r
+\r
+Name: org/eclipse/jface/preference/ColorFieldEditor$1.class\r
+SHA1-Digest: /dlrN7rz7cGYiKw+ymGS0JAMg/A=\r
+\r
+Name: org/eclipse/jface/action/SubCoolBarManager.class\r
+SHA1-Digest: 3S9WsZ1ty0oENw1hkGSi4C6M5qk=\r
+\r
+Name: plugin.properties\r
+SHA1-Digest: tWNH3hrisFHSrwmu2D5aiafbnjw=\r
+\r
+Name: org/eclipse/jface/action/ActionContributionItem$1.class\r
+SHA1-Digest: TFpLnlsSJIZhyyqHWFxV0icGVj8=\r
+\r
+Name: org/eclipse/jface/bindings/keys/formatting/NativeKeyFormatter.pr\r
+ operties\r
+SHA1-Digest: Hi7YkOmGtbLmnfhvmhwGOJy0mLQ=\r
+\r
+Name: org/eclipse/jface/window/ToolTip.class\r
+SHA1-Digest: TaTQGa/W1JCTtNn9/aHlYdMW++4=\r
+\r
+Name: org/eclipse/jface/dialogs/ProgressMonitorDialog$ProgressMonitor.\r
+ class\r
+SHA1-Digest: ADo2Enwrh9VAIYhx0eGEpP+N+/s=\r
+\r
+Name: org/eclipse/jface/bindings/IBindingManagerListener.class\r
+SHA1-Digest: dc6u6FbL/18eNjT71elM3xdOj9Q=\r
+\r
+Name: org/eclipse/jface/preference/ComboFieldEditor$1.class\r
+SHA1-Digest: qFgA2vKOcH6inGwrZhEhJnnY5XE=\r
+\r
+Name: org/eclipse/jface/viewers/ColumnViewer$1.class\r
+SHA1-Digest: iz5SYN6ITjkuL0Qjthf37rF5Aho=\r
+\r
+Name: org/eclipse/jface/dialogs/ErrorDialog$1.class\r
+SHA1-Digest: 6D/zwylihOWzoZEZV+kOV27KUiE=\r
+\r
+Name: org/eclipse/jface/viewers/ICheckStateListener.class\r
+SHA1-Digest: OV9Nl3s2BO9SJ3FsqDJpAbTuhg8=\r
+\r
+Name: org/eclipse/jface/dialogs/TrayDialog.class\r
+SHA1-Digest: MOh+A0wmNDwUD+mJwSbG8JRS/QE=\r
+\r
+Name: org/eclipse/jface/viewers/StructuredViewer$4.class\r
+SHA1-Digest: ip8lX75vIV+lmBMBALS6SObisow=\r
+\r
+Name: org/eclipse/jface/viewers/IStructuredSelection.class\r
+SHA1-Digest: 2tK+qLoIYEVAHeZsAknZWaP81Cg=\r
+\r
+Name: org/eclipse/jface/util/DelegatingDropAdapter$3.class\r
+SHA1-Digest: 9gSxvKNaCXDrw8efwKEHX3pQvos=\r
+\r
+Name: org/eclipse/jface/fieldassist/DecoratedField$5.class\r
+SHA1-Digest: 0jLFM4I3R9GAX5crkraZ82ZQZmE=\r
+\r
+Name: org/eclipse/jface/viewers/TreeViewer.class\r
+SHA1-Digest: GN/nRmwm7nY2okxXifzNLCSljTQ=\r
+\r
+Name: org/eclipse/jface/fieldassist/ContentProposalAdapter$11.class\r
+SHA1-Digest: CGcS4ZFi37GyVUoAJiQTSJ8lMGk=\r
+\r
+Name: org/eclipse/jface/action/AbstractGroupMarker.class\r
+SHA1-Digest: XQnug1YGBO0kQJO6MQRVDZpdFX0=\r
+\r
+Name: org/eclipse/jface/menus/IMenuStateIds.class\r
+SHA1-Digest: yOEupcQIPltveAoeYJ9O0mgXIDE=\r
+\r
+Name: org/eclipse/jface/preference/ColorSelector$2.class\r
+SHA1-Digest: bsH9bjZUChnZnzpn9c+PfH9+AwM=\r
+\r
+Name: org/eclipse/jface/viewers/ILazyContentProvider.class\r
+SHA1-Digest: lspzBOZYqKBFQe1uN2QkD0KwZXM=\r
+\r
+Name: org/eclipse/jface/action/StatusLine$3.class\r
+SHA1-Digest: je2hwk5H86vP06oYxuce5TqXpuw=\r
+\r
+Name: org/eclipse/jface/action/MenuManager.class\r
+SHA1-Digest: w/Bn0jkvfT25xHfhqwtFS4BQ0ug=\r
+\r
+Name: org/eclipse/jface/wizard/IWizardNode.class\r
+SHA1-Digest: X/fmztQYyvWDgMV0KsNv+ih23WQ=\r
+\r
+Name: org/eclipse/jface/fieldassist/images/required_field_cue.gif\r
+SHA1-Digest: kFgJwSfgjrz6DeAnyTG8VwiYBro=\r
+\r
+Name: org/eclipse/jface/viewers/IDelayedLabelDecorator.class\r
+SHA1-Digest: v7JhOkUsV2uR7TQyAUSJ8ll2lII=\r
+\r
+Name: org/eclipse/jface/viewers/SWTFocusCellManager$2.class\r
+SHA1-Digest: mybS+mcAjjKwYStuiXB8Xw9gALc=\r
+\r
+Name: org/eclipse/jface/viewers/ILabelDecorator.class\r
+SHA1-Digest: fIvm/v7b86gWCRMVsBpm1/EpXGQ=\r
+\r
+Name: org/eclipse/jface/dialogs/PopupDialog$6.class\r
+SHA1-Digest: JxolexrtUJ8/4r25uSSal7mn1Ho=\r
+\r
+Name: org/eclipse/jface/viewers/OwnerDrawLabelProvider$3.class\r
+SHA1-Digest: EuR5vMrQ+HR/wifGMLjmayZxhWs=\r
+\r
+Name: org/eclipse/jface/viewers/ColumnViewerEditorDeactivationEvent.cl\r
+ ass\r
+SHA1-Digest: 4xZJLS/ZALs2kxTN1rQt1VurDSY=\r
+\r
+Name: org/eclipse/jface/dialogs/ControlAnimator.class\r
+SHA1-Digest: cpu/ClpckOMkv+scejHIQGqJU5A=\r
+\r
+Name: org/eclipse/jface/resource/jfacefonts_sunos.properties\r
+SHA1-Digest: HrsLzqtlY256rEtTO16bpSdax4c=\r
+\r
+Name: org/eclipse/jface/fieldassist/images/contassist_ovr.gif\r
+SHA1-Digest: 57qSW9uQioUmE5UdvgvmFM8F+b0=\r
+\r
+Name: org/eclipse/jface/viewers/CellEditor$LayoutData.class\r
+SHA1-Digest: I6whnxT8y74ZaGRq+gHGe5bJ3j4=\r
+\r
+Name: org/eclipse/jface/resource/jfacefonts_linux_gtk.properties\r
+SHA1-Digest: Oo2DBUcSZfvWdidnAFd6RKVFHrw=\r
+\r
+Name: org/eclipse/jface/dialogs/IconAndMessageDialog$1.class\r
+SHA1-Digest: +aiCa3azGCdIliM7kCO26GoeN50=\r
+\r
+Name: org/eclipse/jface/util/SafeRunnable.class\r
+SHA1-Digest: 3YyIwI9dR006n4vFQ6zPzQJpv3Y=\r
+\r
+Name: META-INF/eclipse.inf\r
+SHA1-Digest: SAqY+5ITAL0mkdYeijlSRhyIaZk=\r
+\r
+Name: org/eclipse/jface/layout/AbstractColumnLayout$1.class\r
+SHA1-Digest: uftACdFIsdtuxsTknO5MIeCVIFw=\r
+\r
+Name: org/eclipse/jface/util/DelegatingDragAdapter$2.class\r
+SHA1-Digest: A7/v7QBKBYyFeNiQO0gtzPMz6FQ=\r
+\r
+Name: org/eclipse/jface/dialogs/PageChangedEvent.class\r
+SHA1-Digest: WIEUtq749x6EYR6qUTFO6s9BXyE=\r
+\r
+Name: org/eclipse/jface/util/Policy$2.class\r
+SHA1-Digest: el4nezY2lboq2UA4cEQVvp+DFyk=\r
+\r
+Name: org/eclipse/jface/preference/ListEditor$1.class\r
+SHA1-Digest: hOS4vTAwITe63OK69gRtrgdGvfY=\r
+\r
+Name: org/eclipse/jface/dialogs/PopupDialog$PersistBoundsAction.class\r
+SHA1-Digest: q3r/UgLWuZYH027UVQ1ijbRuywg=\r
+\r
+Name: org/eclipse/jface/viewers/deferred/DeferredContentProvider$Table\r
+ ViewerAdapter.class\r
+SHA1-Digest: v4PTzyzSS/bNn2x31k8dS1VH4MM=\r
+\r
+Name: org/eclipse/jface/preference/PreferenceStore.class\r
+SHA1-Digest: iHIiOHR1kcn10bvJJqhWqcoDFUA=\r
+\r
+Name: org/eclipse/jface/viewers/TreeViewerFocusCellManager.class\r
+SHA1-Digest: Rg33tiTXenal1c2q7KsWbIg4Vxg=\r
+\r
+Name: org/eclipse/jface/preference/FontFieldEditor$1.class\r
+SHA1-Digest: D95MQhuRclaek/BfU9j6G+4JIzU=\r
+\r
+Name: org/eclipse/jface/viewers/ColumnViewerEditor$1.class\r
+SHA1-Digest: lvHU+SbHKPlAYsrhA514+l8T8sI=\r
+\r
+Name: org/eclipse/jface/dialogs/images/message_info.gif\r
+SHA1-Digest: 4+5SUEYuS/dj4a895j9IOruyRMY=\r
+\r
+Name: org/eclipse/jface/dialogs/ControlEnableState$ItemState.class\r
+SHA1-Digest: MNcQJ60aixDqZgIyFFeOGA1fudU=\r
+\r
+Name: org/eclipse/jface/resource/FileImageDescriptor.class\r
+SHA1-Digest: mNk+JLnHPWQbdAFaCa+OZ3kX6kw=\r
+\r
+Name: org/eclipse/jface/viewers/TreeViewer$2.class\r
+SHA1-Digest: 0bHaCc7F8zeV/hDl/f1nwNvUL4g=\r
+\r
+Name: org/eclipse/jface/bindings/keys/KeySequenceText$2.class\r
+SHA1-Digest: RL67nF6sxbH1BT7xkNMaZ63pdas=\r
+\r
+Name: org/eclipse/jface/viewers/CheckboxTableViewer$1.class\r
+SHA1-Digest: sk0LD9EDw+X2tvFOgGxPlClIJqU=\r
+\r
+Name: org/eclipse/jface/fieldassist/ContentProposalAdapter$8.class\r
+SHA1-Digest: t0pjQVNqMRqxwJdjC9/BvOZSD5g=\r
+\r
+Name: org/eclipse/jface/viewers/StructuredViewer$UpdateItemSafeRunnabl\r
+ e.class\r
+SHA1-Digest: uMBa4hk48TSMlVv6ufekAsZZwu8=\r
+\r
+Name: org/eclipse/jface/viewers/CheckboxCellEditor.class\r
+SHA1-Digest: fxy0K42NYAEraNzB0zmJ65Xc2DM=\r
+\r
+Name: org/eclipse/jface/viewers/TreeSelection$InitializeData.class\r
+SHA1-Digest: ZRPxfeO9CZpleerkNJnnTG9TJ14=\r
+\r
+Name: org/eclipse/jface/bindings/keys/KeySequenceText.class\r
+SHA1-Digest: MTtYd60chLP3u/JyQhN2PIiQbBw=\r
+\r
+Name: org/eclipse/jface/fieldassist/ControlDecoration$4.class\r
+SHA1-Digest: al2vN1FYLYpSMHMCAxokIPATtOk=\r
+\r
+Name: org/eclipse/jface/fieldassist/IContentProposalListener2.class\r
+SHA1-Digest: I5IQUeHrSrr0RNUuN2LA5fD/sfw=\r
+\r
+Name: org/eclipse/jface/window/ToolTip$TooltipHideListener.class\r
+SHA1-Digest: AWowHswa0UE/EOOAhC6SYztBPJo=\r
+\r
+Name: org/eclipse/jface/viewers/IBaseLabelProvider.class\r
+SHA1-Digest: CcLat4gZgEPhu/B2W4WMQlnlC5I=\r
+\r
+Name: org/eclipse/jface/util/OpenStrategy.class\r
+SHA1-Digest: T0mxgRh4jSaKco8V4MCNtuVqfV4=\r
+\r
+Name: org/eclipse/jface/preference/PreferenceDialog$6.class\r
+SHA1-Digest: 7PcTTaLAGPxbyetOasLBK/b6Wjo=\r
+\r
+Name: org/eclipse/jface/wizard/WizardDialog$2.class\r
+SHA1-Digest: 8uA3wtws8z7jD43kdW+r8vnw34A=\r
+\r
+Name: org/eclipse/jface/util/SafeRunnable$1.class\r
+SHA1-Digest: 2umWrfjksQ0MS70+JG2x2RzbLAY=\r
+\r
+Name: org/eclipse/jface/preference/PreferenceDialog$11.class\r
+SHA1-Digest: O02NzqZ0AbJKtR+2NCYptxcgSgM=\r
+\r
+Name: org/eclipse/jface/resource/LocalResourceManager$1.class\r
+SHA1-Digest: jpcFMI4RCk5T966O5yLGI/lP7rQ=\r
+\r
+Name: org/eclipse/jface/viewers/deferred/IntHashMap.class\r
+SHA1-Digest: o6kUSud7+tn1YgigbdcAju/O8ug=\r
+\r
+Name: org/eclipse/jface/viewers/CellEditor$1.class\r
+SHA1-Digest: Mr9pauGbra0I693a/ptImT7QNTY=\r
+\r
+Name: org/eclipse/jface/dialogs/images/help.gif\r
+SHA1-Digest: 0yYw/cn9njN3clSzHx43MdH0L7k=\r
+\r
+Name: org/eclipse/jface/action/StatusLine.class\r
+SHA1-Digest: kzn2ZEdHZIUeJYd95zXPGZ9D07Q=\r
+\r
+Name: org/eclipse/jface/dialogs/PopupDialog$1.class\r
+SHA1-Digest: VWwFVyqkzncebypKrPsWlYQ5S3o=\r
+\r
+Name: org/eclipse/jface/contexts/IContextIds.class\r
+SHA1-Digest: DDvZqTHQrgoS8gP7axmOLICx2S4=\r
+\r
+Name: org/eclipse/jface/viewers/TreeNodeContentProvider.class\r
+SHA1-Digest: jDb6XqU8SpxJb1jCjFzcCxwEHMA=\r
+\r
+Name: org/eclipse/jface/action/ContributionItem.class\r
+SHA1-Digest: cYRyTsQtAPnjToLzl6ZjMy/hfQ0=\r
+\r
+Name: org/eclipse/jface/action/Action$1.class\r
+SHA1-Digest: qD4GQNN/CLnK+K7WmoglJUHzTDQ=\r
+\r
+Name: org/eclipse/jface/preference/PreferenceDialog.class\r
+SHA1-Digest: 2D9l2J3eK+35A6dz+z6WxmcgVgY=\r
+\r
+Name: org/eclipse/jface/layout/LayoutConstants.class\r
+SHA1-Digest: yX2rsxqXNPU5sCfYsVUR9QxzTuA=\r
+\r
+Name: org/eclipse/jface/viewers/TreeViewerFocusCellManager$1.class\r
+SHA1-Digest: X81rPyD+S5fd7kuwoVVMrFpa2xY=\r
+\r
+Name: org/eclipse/jface/viewers/TableColumnViewerLabelProvider.class\r
+SHA1-Digest: 9HqbbhBAsNP2f5i3+7CyC0ALW8M=\r
+\r
+Name: org/eclipse/jface/viewers/IColorDecorator.class\r
+SHA1-Digest: BWmbSGHnKYvj2Dh/DteJ4bjUCNY=\r
+\r
+Name: org/eclipse/jface/viewers/ILightweightLabelDecorator.class\r
+SHA1-Digest: kbo1qzUrH3zJV+I4GJ4WYhJW37A=\r
+\r
+Name: org/eclipse/jface/operation/AccumulatingProgressMonitor$Collecto\r
+ r.class\r
+SHA1-Digest: D5ShG7fV9bGwCiCOH/HqHahMIMc=\r
+\r
+Name: org/eclipse/jface/viewers/DialogCellEditor$2.class\r
+SHA1-Digest: snWPTjmEFYjOXdgJykp5WD3nBgo=\r
+\r
+Name: org/eclipse/jface/viewers/AbstractTreeViewer$6.class\r
+SHA1-Digest: vg6+OjDls3q+Cj1LIAGgBeBf1JA=\r
+\r
+Name: org/eclipse/jface/resource/ImageDataImageDescriptor.class\r
+SHA1-Digest: DtD9W5VBTkzJWIvPamlI2whyxxM=\r
+\r
+Name: org/eclipse/jface/dialogs/TrayDialog$1.class\r
+SHA1-Digest: 3UC9Kt03AvXFuUEjAxkUK3AV7S0=\r
+\r
+Name: org/eclipse/jface/util/DelegatingDragAdapter.class\r
+SHA1-Digest: HEm5T4B0tN97W71IQJHkuxkl/ME=\r
+\r
+Name: org/eclipse/jface/internal/provisional/action/ToolBarContributio\r
+ nItem2.class\r
+SHA1-Digest: 7NFzkt09eqSgxjsqTOZSN8/kd/0=\r
+\r
+Name: org/eclipse/jface/viewers/TableViewer$1.class\r
+SHA1-Digest: LC6wzgZN/wfh3UraLeZFFE80SPs=\r
+\r
+Name: org/eclipse/jface/viewers/AbstractTableViewer$3.class\r
+SHA1-Digest: b6kXtpeNnCl0tx2H1/CSghMyh5Y=\r
+\r
+Name: org/eclipse/jface/util/ListenerList.class\r
+SHA1-Digest: JRJeqTnvP2boO9uai9RqVB94gOI=\r
+\r
+Name: org/eclipse/jface/resource/JFaceResources.class\r
+SHA1-Digest: aBrxtrcskDguKeazeyN6LeXTjiM=\r
+\r
+Name: org/eclipse/jface/viewers/TableTreeViewer$2.class\r
+SHA1-Digest: JdoC3DlW5WKUwKNSeqyOaW6Eeno=\r
+\r
+Name: org/eclipse/jface/util/LocalSelectionTransfer.class\r
+SHA1-Digest: xzoMAPMzcDGE7EikpP41APaTenY=\r
+\r
+Name: org/eclipse/jface/preference/StringFieldEditor.class\r
+SHA1-Digest: hwIsBB9NjnOJkV9XuJ1DIUtwLm4=\r
+\r
+Name: org/eclipse/jface/action/ExternalActionManager$1.class\r
+SHA1-Digest: 1WRJ6ds7CVEcEbVII/YjjyBN1Qo=\r
+\r
+Name: org/eclipse/jface/fieldassist/ContentProposalAdapter$3.class\r
+SHA1-Digest: T5UsNG6YLa+//AKyPrXFLUG4/Ho=\r
+\r
+Name: org/eclipse/jface/viewers/WrappedViewerLabelProvider.class\r
+SHA1-Digest: cdGH5ez8CNa4MzvRw3PCrUt+hC4=\r
+\r
+Name: org/eclipse/jface/viewers/TextCellEditor$6.class\r
+SHA1-Digest: Njh00JUQgN9MHQuTdI0SrWLBz5I=\r
+\r
+Name: org/eclipse/jface/viewers/AbstractTableViewer.class\r
+SHA1-Digest: EG7QRmsCmDmAon+tAwth25np7qo=\r
+\r
+Name: org/eclipse/jface/operation/ModalContext$1.class\r
+SHA1-Digest: zrfgG4topJmDQxmT/TGLPpaV/SI=\r
+\r
+Name: org/eclipse/jface/action/ControlContribution.class\r
+SHA1-Digest: 9IIz8uXykWOv7BrbG3FKwax8qVs=\r
+\r
+Name: org/eclipse/jface/bindings/Scheme.class\r
+SHA1-Digest: n35jC969b3ntgi+35SH+MVZO6vY=\r
+\r
+Name: org/eclipse/jface/preference/PreferenceDialog$1.class\r
+SHA1-Digest: A0X4U+JozQ5bpnMZ5dnxKdX42jU=\r
+\r
+Name: org/eclipse/jface/preference/PreferenceStore$1.class\r
+SHA1-Digest: 01ON1xif/rXBcumyCBomc8WUaEY=\r
+\r
+Name: org/eclipse/jface/resource/LocalResourceManager.class\r
+SHA1-Digest: bCV1WrTJ9PvyU+0N2MZoxgvTcrM=\r
+\r
+Name: org/eclipse/jface/resource/DeviceResourceDescriptor.class\r
+SHA1-Digest: nlVoMy25VQqSg3kq6dYnXH9ySUg=\r
+\r
+Name: org/eclipse/jface/operation/AccumulatingProgressMonitor$1.class\r
+SHA1-Digest: /AzVTwzR5tozuEwYPHJlzhhtIu0=\r
+\r
+Name: org/eclipse/jface/util/SafeRunnableDialog$2.class\r
+SHA1-Digest: fvMnOCEMp1oh6O+jh025+Wn+P2A=\r
+\r
+Name: org/eclipse/jface/dialogs/IMessageProvider.class\r
+SHA1-Digest: jtqJpxCW3PevB3d0w8G1duZSQZc=\r
+\r
+Name: org/eclipse/jface/fieldassist/images/warn_ovr.gif\r
+SHA1-Digest: QinaeVEnreHLqsEwedtOOmgyv9Q=\r
+\r
+Name: org/eclipse/jface/bindings/BindingManagerEvent.class\r
+SHA1-Digest: lMe5xyhkfCpuxXj88lUc0KtswF8=\r
+\r
+Name: org/eclipse/jface/preference/PreferenceConverter.class\r
+SHA1-Digest: HMRPHyQ6nY8s5WlcVEnXessWmwM=\r
+\r
+Name: org/eclipse/jface/operation/AccumulatingProgressMonitor.class\r
+SHA1-Digest: c/mTOmIPdA06EK03KIWbmFpE0jM=\r
+\r
+Name: org/eclipse/jface/bindings/keys/KeySequenceText$TraversalFilter.\r
+ class\r
+SHA1-Digest: u3c557X0JoNUTbacV6WwXeY8RMA=\r
+\r
+Name: org/eclipse/jface/viewers/AbstractTreeViewer$1.class\r
+SHA1-Digest: ZeRLuay83LgukkB/mePMfrXGfi8=\r
+\r
+Name: org/eclipse/jface/preference/IPreferencePageContainer.class\r
+SHA1-Digest: /KfDDJ25D9yh1qmw/PfvLCS+uqg=\r
+\r
+Name: org/eclipse/jface/viewers/CustomHashtable.class\r
+SHA1-Digest: oqESqdnwGRChPAgfopSQlu+EZqQ=\r
+\r
+Name: org/eclipse/jface/action/ActionContributionItem$2.class\r
+SHA1-Digest: 1zi9buG+O1MFNklL5LFFvcZzPgo=\r
+\r
+Name: org/eclipse/jface/viewers/ColumnViewer$2.class\r
+SHA1-Digest: bLlDGWKfdwjMvgp3kiGGg53/gNg=\r
+\r
+Name: org/eclipse/jface/viewers/StructuredViewer$5.class\r
+SHA1-Digest: 1/CO04abNoxxMr9jtI0fnton1AM=\r
+\r
+Name: org/eclipse/jface/action/ToolBarManager$1.class\r
+SHA1-Digest: aNYdmr+bnL9pl4sapwQXHlAYC5o=\r
+\r
+Name: org/eclipse/jface/util/DelegatingDropAdapter$4.class\r
+SHA1-Digest: 8Hal+63xM4XsoHyOppkphaGyGDw=\r
+\r
+Name: org/eclipse/jface/viewers/AbstractTreeViewer.class\r
+SHA1-Digest: wKz0Wo41oX43cnST0s4md/jBVVU=\r
+\r
+Name: org/eclipse/jface/fieldassist/ContentProposalAdapter$12.class\r
+SHA1-Digest: kh2CM6jdnIUNfyG+282GJzeIuTU=\r
+\r
+Name: org/eclipse/jface/viewers/CheckStateChangedEvent.class\r
+SHA1-Digest: Ksus+UUE8tLT+SYKEV39ZJmLu0c=\r
+\r
+Name: org/eclipse/jface/action/ExternalActionManager$ICallback.class\r
+SHA1-Digest: oJZaOdjbc14XnVnpSuFcGiaiHXE=\r
+\r
+Name: org/eclipse/jface/preference/ColorSelector$3.class\r
+SHA1-Digest: kJN187i+2VU+gpx09+nrkbzSWIA=\r
+\r
+Name: org/eclipse/jface/preference/IPreferenceStore.class\r
+SHA1-Digest: etOMu/+F26Hd4DQ4KkQWoXnSS0w=\r
+\r
+Name: org/eclipse/jface/commands/ActionHandler$1.class\r
+SHA1-Digest: kFsiZrJvnHz+KzTZcfXupcur3Cg=\r
+\r
+Name: org/eclipse/jface/action/StatusLine$4.class\r
+SHA1-Digest: njb6+cRh3pIXNlrC48vDj1TO7aM=\r
+\r
+Name: org/eclipse/jface/viewers/TextCellEditor$1.class\r
+SHA1-Digest: JqelNAvQD3QOoG4eQ5lFCAJhbuQ=\r
+\r
+Name: org/eclipse/jface/preference/FileFieldEditor.class\r
+SHA1-Digest: 7ysHkCAetehqJ1fJ37FT/sS652c=\r
+\r
+Name: org/eclipse/jface/resource/JFaceColors.class\r
+SHA1-Digest: daJm7rWnOWWo+gNUVYTq7evSuhg=\r
+\r
+Name: org/eclipse/jface/viewers/ContentViewer$1.class\r
+SHA1-Digest: Tb2gpdo/UFpbU6tYXXetzGKSZkk=\r
+\r
+Name: org/eclipse/jface/action/ToolBarContributionItem$1.class\r
+SHA1-Digest: 4agIFkSYnP6ZG8eDb9AKy6TKwY8=\r
+\r
+Name: org/eclipse/jface/viewers/SWTFocusCellManager$3.class\r
+SHA1-Digest: NivKVpSWAl0azOv0HnW05x+iCb8=\r
+\r
+Name: org/eclipse/jface/viewers/ColorCellEditor.class\r
+SHA1-Digest: 1eYDNxHZ2akrgbxKPqk5KB6LgLk=\r
+\r
+Name: org/eclipse/jface/dialogs/PopupDialog$7.class\r
+SHA1-Digest: +yf4gB57nfKVmo/u4tQNwptAa0w=\r
+\r
+Name: org/eclipse/jface/viewers/OpenEvent.class\r
+SHA1-Digest: 1XwKuWw+QBj+I3EwXmTt31jrado=\r
+\r
+Name: org/eclipse/jface/viewers/ViewerDropAdapter.class\r
+SHA1-Digest: mlvfm7I8PgwWpTh/lDohNk+ax84=\r
+\r
+Name: org/eclipse/jface/resource/DeviceResourceException.class\r
+SHA1-Digest: uxAb9MGXDAiCL5RGXF2ZjhpimDU=\r
+\r
+Name: org/eclipse/jface/wizard/ProgressMonitorPart$1.class\r
+SHA1-Digest: NiC6gjQ5rX5449Yb8M5bnPGdj0s=\r
+\r
+Name: org/eclipse/jface/layout/TableColumnLayout.class\r
+SHA1-Digest: XMzM+DeJTdp22sAn/x/Hyt2VJFw=\r
+\r
+Name: org/eclipse/jface/util/TransferDragSourceListener.class\r
+SHA1-Digest: Lo+s2yClbDS/EOSaLAh0t8LknRU=\r
+\r
+Name: org/eclipse/jface/resource/ImageRegistry$Entry.class\r
+SHA1-Digest: QLTfXd/FfRauy2UDzd7vc4j4ODg=\r
+\r
+Name: org/eclipse/jface/dialogs/IconAndMessageDialog$2.class\r
+SHA1-Digest: QmnFoW7LvPgnpOzwddsZ7pXdEFM=\r
+\r
+Name: org/eclipse/jface/fieldassist/ContentProposalAdapter$ContentProp\r
+ osalPopup$InfoPopupDialog.class\r
+SHA1-Digest: 46FdyvKh6mxXeXggcOd+79FMORU=\r
+\r
+Name: org/eclipse/jface/action/ExternalActionManager$CommandCallback.c\r
+ lass\r
+SHA1-Digest: y1BMAs9flPxZTeHzWuOg7mt4uBA=\r
+\r
+Name: org/eclipse/jface/viewers/ILabelProviderListener.class\r
+SHA1-Digest: 7lvrA7c4Tu134DZ/RkkAq0+FkWI=\r
+\r
+Name: org/eclipse/jface/preference/FontFieldEditor$DefaultPreviewer.cl\r
+ ass\r
+SHA1-Digest: SGcmnjbSBLnFLzCe/+1jq9NxWGg=\r
+\r
+Name: org/eclipse/jface/menus/IWidget.class\r
+SHA1-Digest: aUOhQ5T6SKmfDMgKY+KkmtY4fHs=\r
+\r
+Name: org/eclipse/jface/util/DelegatingDragAdapter$3.class\r
+SHA1-Digest: X9F2HmEVsPY7vDHwx/qZItNU4bc=\r
+\r
+Name: org/eclipse/jface/viewers/ColorCellEditor$ColorCellLayout.class\r
+SHA1-Digest: YBMAPPB9vChppwxBXfJwh39UWmk=\r
+\r
+Name: org/eclipse/jface/action/IMenuListener2.class\r
+SHA1-Digest: R/MdrqiSzQ37sbpZiCk1phECly8=\r
+\r
+Name: org/eclipse/jface/viewers/ViewerFilter.class\r
+SHA1-Digest: t+nuhqWFFJGZxb6aSB9AjA/C3Q8=\r
+\r
+Name: org/eclipse/jface/viewers/CellNavigationStrategy.class\r
+SHA1-Digest: t7zgt9DFW69vZjfZyKkM54oaVds=\r
+\r
+Name: org/eclipse/jface/preference/ListEditor$2.class\r
+SHA1-Digest: uqBpVSQXSFff7+XV8whd07w0Am0=\r
+\r
+Name: org/eclipse/jface/preference/FontFieldEditor$2.class\r
+SHA1-Digest: 4n9mTboTrvaf5IqBpiAS/t77Ntc=\r
+\r
+Name: org/eclipse/jface/window/ToolTip$1.class\r
+SHA1-Digest: Xr4jmabxBEobgAbGzhobygnHHUg=\r
+\r
+Name: org/eclipse/jface/viewers/ColumnViewerEditor$2.class\r
+SHA1-Digest: u5RtLUKtMTAOPY5cgnwK2WTxbYE=\r
+\r
+Name: org/eclipse/jface/preference/PathEditor.class\r
+SHA1-Digest: +S4cC3zj6w1IBwlZLsUv7oLm6dg=\r
+\r
+Name: org/eclipse/jface/viewers/IContentProvider.class\r
+SHA1-Digest: yO0/5uvnhqoVnY0aoU252XGQMqs=\r
+\r
+Name: org/eclipse/jface/preference/StringFieldEditor$1.class\r
+SHA1-Digest: +h7PqEUBPHe9dVs6Glb6p+1SW4s=\r
+\r
+Name: org/eclipse/jface/viewers/deferred/ConcurrentTableUpdator$Range.\r
+ class\r
+SHA1-Digest: tSTzSK2AFHyShaKYKt55KlkEH8M=\r
+\r
+Name: org/eclipse/jface/viewers/TreeViewer$3.class\r
+SHA1-Digest: 6pGLDoOZ2l8SN7Emn70NXcesheA=\r
+\r
+Name: org/eclipse/jface/viewers/FocusCellOwnerDrawHighlighter$1.class\r
+SHA1-Digest: di6v+upJFKG9ucL8nqeAZoMDUak=\r
+\r
+Name: org/eclipse/jface/viewers/AcceptAllFilter.class\r
+SHA1-Digest: mcK5dWzxY79h0gqQQwmfRj2sJi0=\r
+\r
+Name: org/eclipse/jface/preference/BooleanPropertyAction$1.class\r
+SHA1-Digest: /H3QjxH6oIwXZ3MpjLK/xDAtzQ4=\r
+\r
+Name: org/eclipse/jface/resource/ImageRegistry$OriginalImageDescriptor\r
+ .class\r
+SHA1-Digest: kndwQlmwG27f7lud7fivGfkQtMo=\r
+\r
+Name: org/eclipse/jface/action/IMenuManager.class\r
+SHA1-Digest: VxAA0V4YTQA3UPbS5R6qAtIr00s=\r
+\r
+Name: org/eclipse/jface/fieldassist/SimpleContentProposalProvider.clas\r
+ s\r
+SHA1-Digest: Bi7F4UWh+bvk/arpKt4yxVD9izU=\r
+\r
+Name: org/eclipse/jface/fieldassist/ContentProposalAdapter$9.class\r
+SHA1-Digest: 2P94ZJ12gAxYXNlALN095JT5v5U=\r
+\r
+Name: org/eclipse/jface/viewers/ViewerColumn$1.class\r
+SHA1-Digest: C1JLtvjyhOVTgNwEC3Cb5UmVGLI=\r
+\r
+Name: org/eclipse/jface/viewers/ViewerComparator$1.class\r
+SHA1-Digest: rHUhe73OefEuXW6/ogyqxHRICOQ=\r
+\r
+Name: org/eclipse/jface/viewers/FocusCellOwnerDrawHighlighter.class\r
+SHA1-Digest: AHrjof87KQ32jSl9vIl7GXYzkso=\r
+\r
+Name: org/eclipse/jface/fieldassist/DecoratedField$FieldDecorationData\r
+ .class\r
+SHA1-Digest: gvli4Yn6/gdUOr9bkCdhROLyhPE=\r
+\r
+Name: org/eclipse/jface/dialogs/IPageChangingListener.class\r
+SHA1-Digest: 9l898ZRjO5QC9/xRt+uJEPTnD7w=\r
+\r
+Name: org/eclipse/jface/dialogs/StatusDialog.class\r
+SHA1-Digest: 1XZHKZ+Dxjqy4M8Sz7QEBD8nw8s=\r
+\r
+Name: org/eclipse/jface/preference/FieldEditorPreferencePage.class\r
+SHA1-Digest: RXV/bhU+SPhdEalBQRjfzQiIyEw=\r
+\r
+Name: org/eclipse/jface/viewers/IFilter.class\r
+SHA1-Digest: xYCE0vSQQClAf9RIryXODSxmwlA=\r
+\r
+Name: org/eclipse/jface/fieldassist/DecoratedField$1.class\r
+SHA1-Digest: imMe4RZwy4njTnzTVBTC55+O8pc=\r
+\r
+Name: org/eclipse/jface/fieldassist/ControlDecoration$5.class\r
+SHA1-Digest: 7g1of9yrG55ajsiiXQCMi8HYKtg=\r
+\r
+Name: org/eclipse/jface/action/ActionContributionItem.class\r
+SHA1-Digest: ZTy4o3pmBswP5IHjC53tkPfFIU0=\r
+\r
+Name: org/eclipse/jface/fieldassist/ContentProposalAdapter$ContentProp\r
+ osalPopup$TargetControlListener.class\r
+SHA1-Digest: fbI6CQYQYD5vXLoMUPiYCYWe1xY=\r
+\r
+Name: org/eclipse/jface/dialogs/images/popup_menu.gif\r
+SHA1-Digest: 22R9N09vLbsIdT7NXQIXEHLO9Lk=\r
+\r
+Name: org/eclipse/jface/action/IContributionManager.class\r
+SHA1-Digest: v105cSPG9w6fKeCpKB1384IAEoc=\r
+\r
+Name: org/eclipse/jface/viewers/StructuredSelection.class\r
+SHA1-Digest: sBcdpWLl1DYHvRZTuUaGe252vLo=\r
+\r
+Name: org/eclipse/jface/resource/jfacefonts_windows98.properties\r
+SHA1-Digest: 2yI7jAy587B/b3gaeKWlR0yberc=\r
+\r
+Name: org/eclipse/jface/preference/PreferenceDialog$7.class\r
+SHA1-Digest: p+VppDoo7MPNXkgks/RjC0c+mA0=\r
+\r
+Name: org/eclipse/jface/bindings/BindingManager.class\r
+SHA1-Digest: HANyKX7b2pD/ZLFiNdmIUY7EcAM=\r
+\r
+Name: org/eclipse/jface/resource/ColorDescriptor.class\r
+SHA1-Digest: r5iwKsHsxYahtFRBj4NhOBHT4yo=\r
+\r
+Name: org/eclipse/jface/wizard/WizardDialog$3.class\r
+SHA1-Digest: B/mhds/Dw7TMMDiCXBuXgqEeTzA=\r
+\r
+Name: org/eclipse/jface/util/SafeRunnable$2.class\r
+SHA1-Digest: wZfQcCu8Vt5cb6ZEbofrjvA3FdE=\r
+\r
+Name: org/eclipse/jface/preference/PreferenceDialog$12.class\r
+SHA1-Digest: rvbB9G8QjqV2s4wk84T1p6hGmM0=\r
+\r
+Name: org/eclipse/jface/viewers/CellEditor$2.class\r
+SHA1-Digest: RBTKXY1Ob8f8082JrPE5+cD4qVU=\r
+\r
+Name: org/eclipse/jface/operation/IThreadListener.class\r
+SHA1-Digest: EJR/R98/auL8qd4/lZMVvd9SNg0=\r
+\r
+Name: org/eclipse/jface/dialogs/PopupDialog$2.class\r
+SHA1-Digest: 9ubZ1tB2EbVm2bM61gESQ3CagnQ=\r
+\r
+Name: org/eclipse/jface/viewers/TableViewerRow.class\r
+SHA1-Digest: DPZa2Mk4rUkY3Ge95wDQoBRovX8=\r
+\r
+Name: org/eclipse/jface/viewers/ComboBoxCellEditor$1.class\r
+SHA1-Digest: 8x7+fw7HQSwPwCGavBa1/BLX58A=\r
+\r
+Name: org/eclipse/jface/action/IAction.class\r
+SHA1-Digest: L5aIwRXcSCe6jRjtCxBqbun8lOk=\r
+\r
+Name: org/eclipse/jface/action/ContributionManager.class\r
+SHA1-Digest: UjLZPx2pIBQdiezA9eH9iQGWtlw=\r
+\r
+Name: org/eclipse/jface/viewers/ISelectionProvider.class\r
+SHA1-Digest: 2Xv8rrqYG9g9QQM0YkBJzs57iK4=\r
+\r
+Name: org/eclipse/jface/internal/provisional/action/CoolBarManager2.cl\r
+ ass\r
+SHA1-Digest: idvQDUsvxH0pNAOitAiCBTNpQAw=\r
+\r
+Name: org/eclipse/jface/viewers/CellEditor.class\r
+SHA1-Digest: eCKjKtb0DiHyo/whTjJypi6LcB0=\r
+\r
+Name: org/eclipse/jface/viewers/TreeColumnViewerLabelProvider.class\r
+SHA1-Digest: oDKx3wSOOD/S+AHKfPVJzs/f0Qk=\r
+\r
+Name: org/eclipse/jface/dialogs/IDialogSettings.class\r
+SHA1-Digest: U72D0RrHbbyIGs0bfpr9+jIulqw=\r
+\r
+Name: org/eclipse/jface/viewers/ILazyTreePathContentProvider.class\r
+SHA1-Digest: c+Ba//yLYhEJ/vJfueHLJe0HYPw=\r
+\r
+Name: org/eclipse/jface/viewers/IViewerLabelProvider.class\r
+SHA1-Digest: 9YjMuwc6VGf1I5QZk6nf32f7MrI=\r
+\r
+Name: org/eclipse/jface/resource/ArrayFontDescriptor.class\r
+SHA1-Digest: 0lHb3Pue2/Xeef5+H4MQXPfinbw=\r
+\r
+Name: org/eclipse/jface/viewers/deferred/FastProgressReporter.class\r
+SHA1-Digest: n9yEl7X1i6XW66E/5aiqRgKUCK4=\r
+\r
+Name: org/eclipse/jface/dialogs/DialogSettings$XMLWriter.class\r
+SHA1-Digest: vTc8cA23Ik0PTcK59zdr2npDJ4c=\r
+\r
+Name: org/eclipse/jface/viewers/DialogCellEditor$3.class\r
+SHA1-Digest: Uc1DM1H3WpMM/Jmt9WVVQXV9inQ=\r
+\r
+Name: org/eclipse/jface/viewers/AbstractTreeViewer$7.class\r
+SHA1-Digest: k+CzVBX+X4dBv1Rwi90RKsFvSRk=\r
+\r
+Name: org/eclipse/jface/bindings/keys/SWTKeySupport.class\r
+SHA1-Digest: WxRlv19w5l+xtjFRy2WlGJFo0Dc=\r
+\r
+Name: org/eclipse/jface/dialogs/TrayDialog$2.class\r
+SHA1-Digest: zA+C3XqZnE0zQtB8lg9pBsdb2/U=\r
+\r
+Name: org/eclipse/jface/viewers/IDoubleClickListener.class\r
+SHA1-Digest: QJtV0uJ0RWPasHqjyTNwnx08Fjg=\r
+\r
+Name: org/eclipse/jface/resource/DataFormatException.class\r
+SHA1-Digest: 7CkkwzusO6V1BkM6lxgpMZJyUg0=\r
+\r
+Name: org/eclipse/jface/util/Policy.class\r
+SHA1-Digest: dcIT60UbzgaEyJv+nyepyQ+w8pY=\r
+\r
+Name: org/eclipse/jface/viewers/TableTreeViewer$3.class\r
+SHA1-Digest: BWsEft/KoCOeMQJnP4gesv0VlCg=\r
+\r
+Name: org/eclipse/jface/preference/ScaleFieldEditor$1.class\r
+SHA1-Digest: 5DLE3inzefSlmXvCRKO4l0H1eUA=\r
+\r
+Name: org/eclipse/jface/fieldassist/TextControlCreator.class\r
+SHA1-Digest: OS0lxF4rUfjxim3NVeguh1GWtqk=\r
+\r
+Name: org/eclipse/jface/resource/jfacefonts_aix.properties\r
+SHA1-Digest: mMrn0dBjkyVAqngF/nJgdZKuiCE=\r
+\r
+Name: org/eclipse/jface/resource/ImageRegistry$1.class\r
+SHA1-Digest: GPBar2cqFQ6LKsiaA3m9V3yVrO4=\r
+\r
+Name: org/eclipse/jface/bindings/keys/SWTKeyLookup.class\r
+SHA1-Digest: BpnGjNXP0fF/+JxzEe42zZHOfhg=\r
+\r
+Name: org/eclipse/jface/action/MenuManager$1.class\r
+SHA1-Digest: O6Y5HoPqUa1El/T25ZkF3IbNqNw=\r
+\r
+Name: org/eclipse/jface/dialogs/images/popup_menu_disabled.gif\r
+SHA1-Digest: srJeylJlVeUWnJbChgrmd/099NU=\r
+\r
+Name: org/eclipse/jface/action/ExternalActionManager$2.class\r
+SHA1-Digest: FapsCo5Kpq4h46GwzXnbwekOekM=\r
+\r
+Name: org/eclipse/jface/util/OpenStrategy$1.class\r
+SHA1-Digest: 0vIKHu+LBVxDc2VsRGtcU9z2rPc=\r
+\r
+Name: org/eclipse/jface/fieldassist/ContentProposalAdapter$4.class\r
+SHA1-Digest: wMcvrqnMlGj4k3Sf6OPQI62EMBQ=\r
+\r
+Name: org/eclipse/jface/preference/BooleanPropertyAction.class\r
+SHA1-Digest: xdpLLDpKyzwCZxOMJLWX9tt83cE=\r
+\r
+Name: org/eclipse/jface/dialogs/IPageChangeProvider.class\r
+SHA1-Digest: 33KEh4FFykggcUvH0cLKhOot+b4=\r
+\r
+Name: org/eclipse/jface/wizard/IWizardPage.class\r
+SHA1-Digest: a9+A7BQQkKb0C5X/NVEfv2xMzDU=\r
+\r
+Name: org/eclipse/jface/bindings/keys/formatting/NativeKeyFormatter.cl\r
+ ass\r
+SHA1-Digest: nNeirgwng3yQKzbAWBq0yXhfpX4=\r
+\r
+Name: org/eclipse/jface/preference/PreferenceContentProvider.class\r
+SHA1-Digest: TXHe4L7LXxEdG0n4fxoYT4KjNR0=\r
+\r
+Name: org/eclipse/jface/viewers/TableTreeViewer.class\r
+SHA1-Digest: vNWTlEJEdfV6dO0rkzwVOn6XWOU=\r
+\r
+Name: org/eclipse/jface/resource/ResourceRegistry.class\r
+SHA1-Digest: IOlJqFf+m30Kba/HN8/2Z0JH9X4=\r
+\r
+Name: org/eclipse/jface/preference/PreferencePage$1.class\r
+SHA1-Digest: jLLkIcssdCNQQ/9NkOQZIVjjS+E=\r
+\r
+Name: org/eclipse/jface/fieldassist/images/error_ovr.gif\r
+SHA1-Digest: TK9Xs4Ma2nrknYgS1Uklk4YAfSM=\r
+\r
+Name: org/eclipse/jface/viewers/CustomHashtable$HashEnumerator.class\r
+SHA1-Digest: Uu37f/plY1D80mic7y8t9Kzinng=\r
+\r
+Name: org/eclipse/jface/menus/TextState.class\r
+SHA1-Digest: 7g5CAqZojYeU3Rm9RGK/vdBxflM=\r
+\r
+Name: org/eclipse/jface/operation/ModalContext$ModalContextThread.clas\r
+ s\r
+SHA1-Digest: /yE4JccpKtBesg2AJlbf6LY6ZZ8=\r
+\r
+Name: org/eclipse/jface/preference/PreferenceDialog$2.class\r
+SHA1-Digest: eB0vqHEJNbMfR9Qfx3mawiKrNW8=\r
+\r
+Name: org/eclipse/jface/fieldassist/DecoratedField.class\r
+SHA1-Digest: eWEI1/CKrCJEuR+Kyg9W8/6ZxM8=\r
+\r
+Name: org/eclipse/jface/dialogs/ImageAndMessageArea$1.class\r
+SHA1-Digest: PXMLexLRLhj6zPb5S+097PgFJeo=\r
+\r
+Name: org/eclipse/jface/viewers/ITreeViewerListener.class\r
+SHA1-Digest: J+vdR9Oz9XXy6s3YPB/8CxDT86Y=\r
+\r
+Name: about.html\r
+SHA1-Digest: M+fykt9heyWoEv1LNiIEeBhi/2Q=\r
+\r
+Name: org/eclipse/jface/commands/RadioState.class\r
+SHA1-Digest: dnjLILvfgNta2HYMH4lar7XhbzM=\r
+\r
+Name: org/eclipse/jface/viewers/ArrayContentProvider.class\r
+SHA1-Digest: aYmv1zcRQFD5ATDaEEmL06W56qs=\r
+\r
+Name: org/eclipse/jface/preference/PreferenceManager.class\r
+SHA1-Digest: uarelCwb7g6CbiNeRL8CMoNtK4s=\r
+\r
+Name: org/eclipse/jface/operation/AccumulatingProgressMonitor$2.class\r
+SHA1-Digest: blI9FoBo6jfXM6qPyNC2P66BQR8=\r
+\r
+Name: org/eclipse/jface/bindings/TriggerSequence.class\r
+SHA1-Digest: EUa2iHMv4Q2XmImCqWq/w7Vtwvw=\r
+\r
+Name: org/eclipse/jface/util/SafeRunnableDialog$3.class\r
+SHA1-Digest: nVRwnWunMDAXQh7QVuhuJr1CUe0=\r
+\r
+Name: org/eclipse/jface/viewers/LabelDecorator.class\r
+SHA1-Digest: gvHUWKGx7wppMggBC0ks0kzUnts=\r
+\r
+Name: org/eclipse/jface/action/SubMenuManager.class\r
+SHA1-Digest: 0Md+/otvaw/ER4iqGu7zwECmWIM=\r
+\r
+Name: org/eclipse/jface/viewers/TableTreeViewer$TableTreeEditorImpl.cl\r
+ ass\r
+SHA1-Digest: fdZ61E/DAYVHbuLVK3Zu1Oi9zUA=\r
+\r
+Name: org/eclipse/jface/resource/StringConverter.class\r
+SHA1-Digest: gUPkCjqtAhSx0BjOyJN1AfkkOUY=\r
+\r
+Name: org/eclipse/jface/viewers/AbstractTreeViewer$2.class\r
+SHA1-Digest: 9DhGiE90W8u/nM6zTaiEmMMv+4c=\r
+\r
+Name: org/eclipse/jface/wizard/images/page.gif\r
+SHA1-Digest: cQM0Fq+6Z8epnE5peRkHHEm2ayQ=\r
+\r
+Name: org/eclipse/jface/action/ActionContributionItem$3.class\r
+SHA1-Digest: 3IVcA8A2blqOrSEM/CJJf7mgT6U=\r
+\r
+Name: org/eclipse/jface/action/SubContributionItem.class\r
+SHA1-Digest: oaR20nnISgYYwkwsVh0x/CdjxGg=\r
+\r
+Name: org/eclipse/jface/viewers/ICellEditorListener.class\r
+SHA1-Digest: bIgZl5hilWT8ONJglpXG2+lD9lI=\r
+\r
+Name: org/eclipse/jface/viewers/deferred/LazySortedCollection$1.class\r
+SHA1-Digest: i2+jtJseLuyEDTrpn7fFQq1W0Yk=\r
+\r
+Name: org/eclipse/jface/viewers/ColumnViewer$3.class\r
+SHA1-Digest: f2CbE/zhXzc5QxbYzKV8QRYL4+c=\r
+\r
+Name: org/eclipse/jface/resource/FontRegistry$1.class\r
+SHA1-Digest: BNdXtUNnzdXAtonMtO+inUTaSYM=\r
+\r
+Name: org/eclipse/jface/viewers/StructuredViewer$6.class\r
+SHA1-Digest: Zuvuc3FgTGtFoCiMEhM3b7Ke2qs=\r
+\r
+Name: org/eclipse/jface/util/DelegatingDropAdapter$5.class\r
+SHA1-Digest: STQH4pMPS95e3IvOVMx5F7jXAv4=\r
+\r
+Name: org/eclipse/jface/viewers/LabelProvider.class\r
+SHA1-Digest: rWbjVohCUCmM0No8WPHujncSy4E=\r
+\r
+Name: org/eclipse/jface/fieldassist/ContentProposalAdapter$13.class\r
+SHA1-Digest: Pr5/0MDJVbOWl2Y3EH1/zZnZhqU=\r
+\r
+Name: org/eclipse/jface/internal/provisional/action/ICoolBarManager2.c\r
+ lass\r
+SHA1-Digest: u0tSlPBuPJYOS+zX4M8L0SLHCEk=\r
+\r
+Name: org/eclipse/jface/viewers/TableViewer.class\r
+SHA1-Digest: NCdDifsh8iVwz3Ktfpj4D2Q6RFc=\r
+\r
+Name: org/eclipse/jface/wizard/WizardDialog$PageContainerFillLayout.cl\r
+ ass\r
+SHA1-Digest: SblVjeNMPGVvykTHHg5raLfjahA=\r
+\r
+Name: org/eclipse/jface/resource/jfacefonts.properties\r
+SHA1-Digest: pLlTRGmJKGTnjwooLyohaqVVP1Q=\r
+\r
+Name: org/eclipse/jface/viewers/TextCellEditor$2.class\r
+SHA1-Digest: RBpQmD8f3qL40iSphQ6W1R7xc5Y=\r
+\r
+Name: org/eclipse/jface/action/StatusLine$StatusLineLayout.class\r
+SHA1-Digest: yF+wk875Ggz/Op8tTDT/hOJ2+GM=\r
+\r
+Name: org/eclipse/jface/viewers/ContentViewer$2.class\r
+SHA1-Digest: PEjUSpFy6gXQr0rHKuuN1VAel+Y=\r
+\r
+Name: org/eclipse/jface/action/ToolBarContributionItem$2.class\r
+SHA1-Digest: mZgkllYMKqQiHrWwA5vYcgAdWeU=\r
+\r
+Name: org/eclipse/jface/dialogs/TitleAreaDialog.class\r
+SHA1-Digest: 44UXOjW+XFMC5/yaCcKQs6HFGBk=\r
+\r
+Name: org/eclipse/jface/viewers/StructuredViewer.class\r
+SHA1-Digest: SWxwhUBQk+6h+npZolDNTFPlknc=\r
+\r
+Name: org/eclipse/jface/commands/ActionHandler.class\r
+SHA1-Digest: ym9jCNObCU4o8zZqlZolaulvZQs=\r
+\r
+Name: org/eclipse/jface/dialogs/ProgressMonitorDialog$1.class\r
+SHA1-Digest: Ki3luz87q8F/TQAgkktuJXA3AQo=\r
+\r
+Name: org/eclipse/jface/window/Window$1.class\r
+SHA1-Digest: qJxw+zNqd2wl4GZODZwyW04CEbA=\r
+\r
+Name: org/eclipse/jface/action/SubMenuManager$1.class\r
+SHA1-Digest: 7LQtCfIC1p6IV0A6zoNgPwolGcQ=\r
+\r
+Name: org/eclipse/jface/dialogs/PopupDialog$ResizeAction.class\r
+SHA1-Digest: voMjeDoBoqW/6LT3m1bXW6WHSpo=\r
+\r
+Name: org/eclipse/jface/dialogs/images/title_banner.gif\r
+SHA1-Digest: wBwKg54T7FuojhG33rUCNeYEsBk=\r
+\r
+Name: org/eclipse/jface/layout/TreeColumnLayout$1.class\r
+SHA1-Digest: zKwlYf3OSat9W4KdWfFVAzgW324=\r
+\r
+Name: org/eclipse/jface/window/Window$IExceptionHandler.class\r
+SHA1-Digest: Cg90thTLd8sZLgnp0HvEP9nBFug=\r
+\r
+Name: org/eclipse/jface/preference/ListEditor$3.class\r
+SHA1-Digest: oy8Km+UVzYMhZvVRpq/bN+IPT+U=\r
+\r
+Name: org/eclipse/jface/commands/RadioState$RadioStateManager$RadioGro\r
+ up.class\r
+SHA1-Digest: YiUCaSO3gZRUo07ojpZ1quUjR0s=\r
+\r
+Name: org/eclipse/jface/preference/FontFieldEditor$3.class\r
+SHA1-Digest: geSmCsbAPUpU30hx3tzhR+v0JTE=\r
+\r
+Name: org/eclipse/jface/viewers/ColumnViewerEditor$3.class\r
+SHA1-Digest: ZNeAwT+JTNTYIU+elZMGHHZ/i+I=\r
+\r
+Name: org/eclipse/jface/window/ToolTip$2.class\r
+SHA1-Digest: ZEWNxaczvH/GE/lN+h7d6RWgYek=\r
+\r
+Name: org/eclipse/jface/preference/StringFieldEditor$2.class\r
+SHA1-Digest: GtkSrN6aJFLvjK25EyHKAXHBrvo=\r
+\r
+Name: org/eclipse/jface/viewers/deferred/LazySortedCollection$Edge.cla\r
+ ss\r
+SHA1-Digest: FjMZiTyah3/2WP0BEOC8IFOj6SU=\r
+\r
+Name: org/eclipse/jface/viewers/TableViewerFocusCellManager.class\r
+SHA1-Digest: n1u3zMuOVbmHcFn94RjpJOBqXUw=\r
+\r
+Name: org/eclipse/jface/viewers/TreeViewer$4.class\r
+SHA1-Digest: udYOLAS/2ufp/M3DERlUmmAXm30=\r
+\r
+Name: org/eclipse/jface/util/ILogger.class\r
+SHA1-Digest: eNX1IaWuQk87dxk6lcEJffTsmu0=\r
+\r
+Name: org/eclipse/jface/viewers/ColumnViewerEditorActivationEvent.clas\r
+ s\r
+SHA1-Digest: +Lr0yRFP9kj7amR2ED+uBDZZcF8=\r
+\r
+Name: org/eclipse/jface/viewers/ITableColorProvider.class\r
+SHA1-Digest: wmgsAB35SwZM8BwNOtLCmreFyr0=\r
+\r
+Name: org/eclipse/jface/viewers/ILabelProvider.class\r
+SHA1-Digest: r6gLAjAFliFIrTFVPUmWB/D1X8M=\r
+\r
+Name: org/eclipse/jface/viewers/TreeSelection.class\r
+SHA1-Digest: f4joIQKmTe+Juw2OCgznJc+aO6M=\r
+\r
+Name: org/eclipse/jface/util/SafeRunnableDialog.class\r
+SHA1-Digest: 7AuaaK/kLjP1+nLq2EQbBP9mf7A=\r
+\r
+Name: org/eclipse/jface/viewers/deferred/IConcurrentModelListener.clas\r
+ s\r
+SHA1-Digest: AlSsuiWv/1RO84RuUb4FViH02ic=\r
+\r
+Name: org/eclipse/jface/viewers/deferred/BackgroundContentProvider$1.c\r
+ lass\r
+SHA1-Digest: 8LTW5qNI97wLj9WPEBN4CJSz93s=\r
+\r
+Name: org/eclipse/jface/dialogs/InputDialog$1.class\r
+SHA1-Digest: wP0WAu37Lj+h6aZq76bcwWLAKJg=\r
+\r
+Name: org/eclipse/jface/bindings/keys/formatting/EmacsKeyFormatter.cla\r
+ ss\r
+SHA1-Digest: 0hUeaT8c6mHWJd/+oBvfBCnIYs0=\r
+\r
+Name: org/eclipse/jface/viewers/ViewerColumn$2.class\r
+SHA1-Digest: C7s9vbHbmf0W4BATxnGysnm4Ixs=\r
+\r
+Name: org/eclipse/jface/action/ExternalActionManager$IActiveChecker.cl\r
+ ass\r
+SHA1-Digest: G5Nb6wPZpJCKZmEqLsAwTPrB7Xc=\r
+\r
+Name: org/eclipse/jface/wizard/IWizardContainer2.class\r
+SHA1-Digest: Ty0SM2BT4G17b4ZBiKNB1tA9rvg=\r
+\r
+Name: org/eclipse/jface/viewers/CellLabelProvider.class\r
+SHA1-Digest: R8a5UDueiUxjXGj92sBDgnnRAXE=\r
+\r
+Name: org/eclipse/jface/viewers/IStructuredContentProvider.class\r
+SHA1-Digest: 2FTYYk0MjKz3+PCqKTNXx+21qTI=\r
+\r
+Name: org/eclipse/jface/viewers/StructuredViewer$1.class\r
+SHA1-Digest: acFOO0tUKeliKUoU9S7XzRzqbVw=\r
+\r
+Name: org/eclipse/jface/fieldassist/DecoratedField$2.class\r
+SHA1-Digest: TFqMD6a3zkzCguklz3gG9O3wKtk=\r
+\r
+Name: org/eclipse/jface/fieldassist/ControlDecoration$6.class\r
+SHA1-Digest: Z9QZQi0F443FrjhIUiK15LTFgjY=\r
+\r
+Name: org/eclipse/jface/viewers/deferred/BackgroundContentProvider$Sor\r
+ tThread.class\r
+SHA1-Digest: nz9OWBBdBQ8XzIdhiSeo3r8F2/c=\r
+\r
+Name: org/eclipse/jface/dialogs/Dialog$1.class\r
+SHA1-Digest: XQZG+5/hwLwaftLYOl42OzxNOOs=\r
+\r
+Name: org/eclipse/jface/preference/DirectoryFieldEditor.class\r
+SHA1-Digest: Wo0QhBmnem9HZjtBUvWwQAMm99k=\r
+\r
+Name: org/eclipse/jface/dialogs/IInputValidator.class\r
+SHA1-Digest: FTjnZG1JqzG8fWtZLBBxby8w1jM=\r
+\r
+Name: org/eclipse/jface/preference/PreferenceDialog$8.class\r
+SHA1-Digest: SEHUNkxUvBnTpRjoHBascUrqHgI=\r
+\r
+Name: org/eclipse/jface/viewers/IDecoration.class\r
+SHA1-Digest: hFANTTYtdCm/M61HZVRyWhHSYzw=\r
+\r
+Name: org/eclipse/jface/window/Window$DefaultExceptionHandler.class\r
+SHA1-Digest: AnRDjJ7LRNfS8zveCdyEeDpU5gI=\r
+\r
+Name: org/eclipse/jface/wizard/WizardDialog$4.class\r
+SHA1-Digest: WFzvw1ShLrPg37mAP17gpRPa9fY=\r
+\r
+Name: org/eclipse/jface/preference/images/pref_dialog_title.gif\r
+SHA1-Digest: +f9inxjFleZdqF8QasPKYtOtQts=\r
+\r
+Name: org/eclipse/jface/util/SafeRunnable$3.class\r
+SHA1-Digest: Y84Q2/VKWE8ULQQX1pGZ+W/9AB4=\r
+\r
+Name: org/eclipse/jface/preference/PreferenceDialog$13.class\r
+SHA1-Digest: cKrV8PIN52KBnGjXaFtPChvT2F0=\r
+\r
+Name: org/eclipse/jface/viewers/CellEditor$3.class\r
+SHA1-Digest: n+8Id78pAM4vutmX36qgE8hDwoc=\r
+\r
+Name: org/eclipse/jface/dialogs/PopupDialog$3.class\r
+SHA1-Digest: DIAGv99xi3dYhcVunLEWX5YZrFQ=\r
+\r
+Name: org/eclipse/jface/viewers/ComboBoxCellEditor$2.class\r
+SHA1-Digest: RngLKnOZIAY+9TwE7QN165zaGU8=\r
+\r
+Name: org/eclipse/jface/window/Window$FontChangeListener.class\r
+SHA1-Digest: HhKZE8ZyvdaraLNI1xoZC+oVMig=\r
+\r
+Name: org/eclipse/jface/viewers/ColumnWeightData.class\r
+SHA1-Digest: U++p8SuVDhCRur15RA8iYcsNJCU=\r
+\r
+Name: org/eclipse/jface/viewers/TreeViewerRow.class\r
+SHA1-Digest: BauA9NOalZJDGBQEqeU1AgOopwo=\r
+\r
+Name: org/eclipse/jface/layout/LayoutGenerator.class\r
+SHA1-Digest: KYt3khyT2KxKIcOV53paU9UnPmc=\r
+\r
+Name: org/eclipse/jface/viewers/IPostSelectionProvider.class\r
+SHA1-Digest: xjw5YPx5EAiAny5uJcz7sMAvhzE=\r
+\r
+Name: org/eclipse/jface/util/Assert$AssertionFailedException.class\r
+SHA1-Digest: sY+Xvd2nNLy+6HJhRvFQ2wC6/vM=\r
+\r
+Name: org/eclipse/jface/dialogs/ImageAndMessageArea.class\r
+SHA1-Digest: eQgMElW7NoVRCXQNviWJTTwrAxI=\r
+\r
+Name: org/eclipse/jface/images/dots_button.gif\r
+SHA1-Digest: aMO48kHOSAa1q3kG1INeOUinOx0=\r
+\r
+Name: org/eclipse/jface/wizard/ProgressMonitorPart.class\r
+SHA1-Digest: y+3AL8O7qaXnGcFKSnIQwJjcDW4=\r
+\r
+Name: org/eclipse/jface/resource/jfacefonts_macosx.properties\r
+SHA1-Digest: vDukkesScCaSuS1N/vKDLy5vLJY=\r
+\r
+Name: org/eclipse/jface/dialogs/PopupDialog.class\r
+SHA1-Digest: P7lNg0bQpNddBiVe4CY0CmYC9bY=\r
+\r
+Name: org/eclipse/jface/util/Util.class\r
+SHA1-Digest: 4Zi4P2yN8kj/0RmvRKHECH19kA4=\r
+\r
+Name: org/eclipse/jface/viewers/ColumnViewerEditorActivationStrategy$1\r
+ .class\r
+SHA1-Digest: 29yx3w38rYqnPHqsbLQHcJPvsa0=\r
+\r
+Name: org/eclipse/jface/bindings/keys/ParseException.class\r
+SHA1-Digest: ERt/VxrP+2MkZpZdJxJ4DnjBGfk=\r
+\r
+Name: org/eclipse/jface/commands/ToggleState.class\r
+SHA1-Digest: zDUpF6DqpLgvtGMl5zDwiVGXPcI=\r
+\r
+Name: org/eclipse/jface/dialogs/StatusDialog$MessageLine.class\r
+SHA1-Digest: M5vGIUZ3D67x8/NwNv2ULanAmt0=\r
+\r
+Name: org/eclipse/jface/viewers/AbstractTreeViewer$8.class\r
+SHA1-Digest: HnClWObvdBQLk7rjxkQ8nLUR+y4=\r
+\r
+Name: org/eclipse/jface/viewers/AbstractTreeViewer$UpdateItemSafeRunna\r
+ ble.class\r
+SHA1-Digest: zw7XcXQrg0C02MfPJUD8ktsMHrQ=\r
+\r
+Name: org/eclipse/jface/viewers/ITreeSelection.class\r
+SHA1-Digest: +F8z26Op0upYoPrfA3pm1e01ebc=\r
+\r
+Name: org/eclipse/jface/dialogs/TrayDialog$3.class\r
+SHA1-Digest: vq0hDaycb0Z3ppgTYHwLJvRQo0g=\r
+\r
+Name: org/eclipse/jface/viewers/ITreeContentProvider.class\r
+SHA1-Digest: 7gb/bVtY4Rzl3UVgCmgg/mPQCDQ=\r
+\r
+Name: org/eclipse/jface/fieldassist/TextContentAdapter.class\r
+SHA1-Digest: Ny050dfIJlel4CzOFQvfGV8UeGw=\r
+\r
+Name: org/eclipse/jface/bindings/keys/KeySequenceText$UpdateSequenceLi\r
+ stener.class\r
+SHA1-Digest: ddcHLbRqDLzzy0WREs8zSu+v+sk=\r
+\r
+Name: org/eclipse/jface/viewers/ColumnLabelProvider.class\r
+SHA1-Digest: VHaJNHpmiZuYwYnCJ6LvSkMCAqQ=\r
+\r
+Name: org/eclipse/jface/viewers/TableTreeViewer$4.class\r
+SHA1-Digest: N9pFGoIvcHk1o+VtAr6K60swRQk=\r
+\r
+Name: org/eclipse/jface/preference/ScaleFieldEditor$2.class\r
+SHA1-Digest: DbEydSGp0pewvPadWAB79W2IpOQ=\r
+\r
+Name: org/eclipse/jface/preference/ListEditor.class\r
+SHA1-Digest: C5wusKhxLf/zzXV7mQIB2qDlDAY=\r
+\r
+Name: org/eclipse/jface/dialogs/images/message_error.gif\r
+SHA1-Digest: 1cph4z9iIwiy2S9c0S/cYT+I3iI=\r
+\r
+Name: org/eclipse/jface/resource/ImageRegistry$2.class\r
+SHA1-Digest: Q29P91VkibEPlLYuajQVG1HPFw8=\r
+\r
+Name: org/eclipse/jface/viewers/EditingSupport.class\r
+SHA1-Digest: yfMP6u+HhNi6W0BSDVxlNDzANsk=\r
+\r
+Name: org/eclipse/jface/action/MenuManager$2.class\r
+SHA1-Digest: ZeZPLHJZJnXEs5Z9+KTNmntNk5o=\r
+\r
+Name: org/eclipse/jface/util/OpenStrategy$2.class\r
+SHA1-Digest: xM2dHa4s9ZDKYlJ2bhSqOqxLRkE=\r
+\r
+Name: org/eclipse/jface/fieldassist/ContentProposalAdapter$5.class\r
+SHA1-Digest: EAq3sdtsWSXV3WIPP0TLtlGI48U=\r
+\r
+Name: org/eclipse/jface/action/GroupMarker.class\r
+SHA1-Digest: RECukQoU4kH9MozQtUeoN4YzYX4=\r
+\r
+Name: org/eclipse/jface/preference/StringButtonFieldEditor$1.class\r
+SHA1-Digest: mBHRuZaMvalRFCGXwP+FW5LPhn8=\r
+\r
+Name: org/eclipse/jface/viewers/TreePathViewerSorter$1.class\r
+SHA1-Digest: 6efAh49omiCnSe5LJzZPyX8v6j8=\r
+\r
+Name: org/eclipse/jface/viewers/CheckboxTableViewer.class\r
+SHA1-Digest: SBjSD0xcqjI2XLx9KytVOMoUh4k=\r
+\r
+Name: org/eclipse/jface/fieldassist/ControlDecoration$1.class\r
+SHA1-Digest: fm5zmAwRHAKwrSpxPwIbZ1Es0Cc=\r
+\r
+Name: org/eclipse/jface/preference/PreferencePage$2.class\r
+SHA1-Digest: BLi85lNcmPGhMUcAG4FyFmtNZRg=\r
+\r
+Name: org/eclipse/jface/layout/GridLayoutFactory.class\r
+SHA1-Digest: 1ixPBQcO24d88JEznt9fOagQk9g=\r
+\r
+Name: org/eclipse/jface/viewers/NamedHandleObjectLabelProvider.class\r
+SHA1-Digest: RpQ1vvqUlcYDYO7kKgG6Wp5czVs=\r
+\r
+Name: org/eclipse/jface/action/ContributionManager$1.class\r
+SHA1-Digest: SX6xIgBnN7AdowIhGKbnCfpB1xY=\r
+\r
+Name: org/eclipse/jface/preference/StringButtonFieldEditor.class\r
+SHA1-Digest: Gc3hsSfRxQINvVoPs7qMgzRNNWg=\r
+\r
+Name: org/eclipse/jface/preference/PreferenceDialog$3.class\r
+SHA1-Digest: UI2Pr1xWjiMDmCUwKVgZeU4+MT4=\r
+\r
+Name: org/eclipse/jface/resource/RGBColorDescriptor.class\r
+SHA1-Digest: Sha6puqMEpI+/CTi1WCXX0Ey9xc=\r
+\r
+Name: org/eclipse/jface/bindings/keys/formatting/KeyFormatterFactory.c\r
+ lass\r
+SHA1-Digest: aduzk4wOIWaXbZe7TXENxrkkamI=\r
+\r
+Name: org/eclipse/jface/resource/MissingImageDescriptor.class\r
+SHA1-Digest: GVzwDdS4Hcf5QQRdYcZs+1ZTdzg=\r
+\r
+Name: org/eclipse/jface/resource/jfacefonts_windowsnt.properties\r
+SHA1-Digest: O8sXG9Pxd+YKWlI4WGbGETZerC0=\r
+\r
+Name: org/eclipse/jface/resource/CompositeImageDescriptor.class\r
+SHA1-Digest: 0Q1r4JDo1ywexXXHLEFyc+mUpQg=\r
+\r
+Name: org/eclipse/jface/dialogs/ImageAndMessageArea$2.class\r
+SHA1-Digest: nQjeywsE58mq4F+cWud6DJtrfSY=\r
+\r
+Name: org/eclipse/jface/viewers/ITreePathContentProvider.class\r
+SHA1-Digest: c3U1VZfwTMXr77Imuv7z1KQSgY4=\r
+\r
+Name: org/eclipse/jface/operation/ModalContext.class\r
+SHA1-Digest: MIyvgca76IoeDGrcKUOTf1+zVAs=\r
+\r
+Name: org/eclipse/jface/viewers/ICheckable.class\r
+SHA1-Digest: rK9QVEZwEdCcusxW3jPnhyKP69s=\r
+\r
+Name: org/eclipse/jface/action/IMenuListener.class\r
+SHA1-Digest: XGLegWw7uJyNCBFMeqhJqeFQq80=\r
+\r
+Name: org/eclipse/jface/dialogs/IDialogConstants.class\r
+SHA1-Digest: F6Q5E9oHkyGl+kdTgOQwIut4YI0=\r
+\r
+Name: org/eclipse/jface/operation/AccumulatingProgressMonitor$3.class\r
+SHA1-Digest: /W3tELlqeYoDMeqi5OpIcwy25oE=\r
+\r
+Name: org/eclipse/jface/fieldassist/ContentProposalAdapter$ContentProp\r
+ osalPopup.class\r
+SHA1-Digest: lR99G8CxSJNu7IU+AQfOo/qzgMs=\r
+\r
+Name: org/eclipse/jface/util/Assert.class\r
+SHA1-Digest: XdV7j5TiXZEMFmkgPoa/X0RuwVQ=\r
+\r
+Name: org/eclipse/jface/viewers/DialogCellEditor$DialogCellLayout.clas\r
+ s\r
+SHA1-Digest: bk25CDJJL7PDwHtRjI35Ui6amOQ=\r
+\r
+Name: org/eclipse/jface/preference/PreferenceNode.class\r
+SHA1-Digest: 6yml3aZl2p9SAdAPAoFHCNWTkQI=\r
+\r
+Name: org/eclipse/jface/action/Action.class\r
+SHA1-Digest: YY+4PWn4Z1MGifXiRcvq3baYrFg=\r
+\r
+Name: org/eclipse/jface/util/SafeRunnableDialog$4.class\r
+SHA1-Digest: UryJn0w04ssNX6KLS8Wz70PXRnY=\r
+\r
+Name: org/eclipse/jface/messages.properties\r
+SHA1-Digest: 1AE74/GTrLZcH6PUlF4unDyg/r0=\r
+\r
+Name: org/eclipse/jface/dialogs/ControlEnableState.class\r
+SHA1-Digest: bNJx0mD0lQAhKw4/eaWoSTXLFl0=\r
+\r
+Name: org/eclipse/jface/viewers/FocusCellHighlighter.class\r
+SHA1-Digest: d6PtIB22jvo+o6to25JX8jSh1zY=\r
+\r
+Name: org/eclipse/jface/viewers/AbstractTreeViewer$3.class\r
+SHA1-Digest: UeNqzpJXcRURKWgx+MpCSZxB03Q=\r
+\r
+Name: org/eclipse/jface/viewers/Viewer$1.class\r
+SHA1-Digest: XZTuWaebhl1SRc3T3suK0pRBeYU=\r
+\r
+Name: org/eclipse/jface/action/ActionContributionItem$4.class\r
+SHA1-Digest: vkPZOQLw+WeldJa9FdYnS3mIKWY=\r
+\r
+Name: org/eclipse/jface/internal/InternalPolicy.class\r
+SHA1-Digest: 7/DN/MbxcrL2BY1KCJQSCHz9GZU=\r
+\r
+Name: org/eclipse/jface/fieldassist/images/errorqf_ovr.gif\r
+SHA1-Digest: Um1Gp9X1ZLQQXPbSn55JPp4zdQE=\r
+\r
+Name: org/eclipse/jface/action/SubStatusLineManager.class\r
+SHA1-Digest: HMQeBJgEcTGjW3WjkHEFGFY54BM=\r
+\r
+Name: org/eclipse/jface/bindings/keys/KeySequenceText$TraversalFilterM\r
+ anager.class\r
+SHA1-Digest: rG7+caEfvMHcnLpB3P+bZcG+JG4=\r
+\r
+Name: org/eclipse/jface/preference/IntegerFieldEditor.class\r
+SHA1-Digest: ZknSkGrFM+5x9rutNtf8J+J18tk=\r
+\r
+Name: org/eclipse/jface/viewers/StructuredViewer$7.class\r
+SHA1-Digest: DfyzSlUVRhku5oAHcaimtTUsMmo=\r
+\r
+Name: org/eclipse/jface/util/DelegatingDropAdapter$6.class\r
+SHA1-Digest: A6O4p4KCOLRlh+aOjcs6HpTY3Ks=\r
+\r
+Name: org/eclipse/jface/fieldassist/ContentProposalAdapter$14.class\r
+SHA1-Digest: PYrRZRMj0hwbSK/zF3Uw/D70shI=\r
+\r
+Name: org/eclipse/jface/dialogs/TitleAreaDialog$1.class\r
+SHA1-Digest: FNeyU+GHMHkrQAwXOVd+5P9nrQg=\r
+\r
+Name: org/eclipse/jface/viewers/Viewer.class\r
+SHA1-Digest: gBkcQUZMqjjBaDHcl1WXyw4RCrY=\r
+\r
+Name: org/eclipse/jface/viewers/deferred/ChangeQueue$Change.class\r
+SHA1-Digest: 9f/YGJeC/TD7LY8woROG6M1fDQE=\r
+\r
+Name: org/eclipse/jface/resource/ResourceManager.class\r
+SHA1-Digest: Dyhj/QDC0ZdNmq0Qtt5rAU/6gw8=\r
+\r
+Name: org/eclipse/jface/action/StatusLineLayoutData.class\r
+SHA1-Digest: T8HPa7xIJIIGPNT46SdWVSXArUE=\r
+\r
+Name: org/eclipse/jface/dialogs/PopupDialog$MoveAction.class\r
+SHA1-Digest: thlMX+3p2Eez56ZbgmddcMXqX6s=\r
+\r
+Name: org/eclipse/jface/wizard/IWizardContainer.class\r
+SHA1-Digest: t6UIOrVi+LgTyr6Ror/O1myGmc8=\r
+\r
+Name: org/eclipse/jface/viewers/TextCellEditor$3.class\r
+SHA1-Digest: A6fAlBwC5yzeFeyV8+yhfbATxIM=\r
+\r
+Name: org/eclipse/jface/viewers/CustomHashtable$EmptyEnumerator.class\r
+SHA1-Digest: iRTEprgJrq6KopjhMrYJO5yq0Nc=\r
+\r
+Name: org/eclipse/jface/preference/ComboFieldEditor.class\r
+SHA1-Digest: VBXzKuE1En4dC8OU8EST0pAg3HU=\r
+\r
+Name: org/eclipse/jface/resource/jfacefonts_windows2000.properties\r
+SHA1-Digest: fNufPvbgB1v0tuy/96aaa7Ox+Ds=\r
+\r
+Name: org/eclipse/jface/fieldassist/ContentProposalAdapter$ContentProp\r
+ osalPopup$PopupCloserListener.class\r
+SHA1-Digest: 5rFpZ7aGwkim8B0mrZyrf41UxRc=\r
+\r
+Name: org/eclipse/jface/util/IPropertyChangeListener.class\r
+SHA1-Digest: NsV5pgvLNCDRe6D77HTE5mbo9Zw=\r
+\r
+Name: org/eclipse/jface/action/ToolBarContributionItem$3.class\r
+SHA1-Digest: u29QnAR7W4XJckBTZigBhlhe9Jo=\r
+\r
+Name: org/eclipse/jface/util/IOpenEventListener.class\r
+SHA1-Digest: O1KuuU6LNLaw4ohBnG8tkPtOVx8=\r
+\r
+Name: org/eclipse/jface/util/DelegatingDropAdapter.class\r
+SHA1-Digest: slrNm/O5OWcqB4nFYluqPlnknp8=\r
+\r
+Name: org/eclipse/jface/bindings/keys/KeySequence.class\r
+SHA1-Digest: T/jhzNZ6gjUuFW17XnTggVHjnW4=\r
+\r
+Name: org/eclipse/jface/preference/JFacePreferences.class\r
+SHA1-Digest: j1Yen4upKix72kc4gM+8V+IT+mQ=\r
+\r
+Name: org/eclipse/jface/viewers/TreeNode.class\r
+SHA1-Digest: pWqn3M1KVaIrkF19WJZJaYd9cx8=\r
+\r
+Name: org/eclipse/jface/internal/provisional/action/IToolBarContributi\r
+ onItem.class\r
+SHA1-Digest: T28GsgkyXThg7Sqi9/guUy3WaCA=\r
+\r
+Name: org/eclipse/jface/viewers/TextCellEditor.class\r
+SHA1-Digest: I/qrH7ONV70oN00F/mD9gLuwUM8=\r
+\r
+Name: org/eclipse/jface/dialogs/ProgressMonitorDialog$2.class\r
+SHA1-Digest: A/1jXUaO26kKR0gcJ676cEmeDWc=\r
+\r
+Name: org/eclipse/jface/wizard/WizardPage.class\r
+SHA1-Digest: 8vTb/Mu1p3w48VRMvf7bS9uVtd0=\r
+\r
+Name: org/eclipse/jface/window/Window$2.class\r
+SHA1-Digest: gn5QsegN1dmrC9AfR+XyR7WryA0=\r
+\r
+Name: org/eclipse/jface/resource/jfacefonts_linux.properties\r
+SHA1-Digest: MPIe46ddE+PVndulixs9MVOt9QM=\r
+\r
+Name: org/eclipse/jface/fieldassist/ControlDecoration$Hover.class\r
+SHA1-Digest: BvM9VBU+lBCxadpvtyYFvpodkqs=\r
+\r
+Name: org/eclipse/jface/dialogs/images/message_warning.gif\r
+SHA1-Digest: NTU6oN3RVw9xXNgd8iqw6yXxmws=\r
+\r
+Name: org/eclipse/jface/commands/RadioState$RadioStateManager.class\r
+SHA1-Digest: 4pf9kmlMExF4NuTbbxwYasNwjxI=\r
+\r
+Name: org/eclipse/jface/resource/DerivedImageDescriptor.class\r
+SHA1-Digest: Z3WfSlMbycShUorbqWYWrcKnAhE=\r
+\r
+Name: org/eclipse/jface/fieldassist/IControlCreator.class\r
+SHA1-Digest: bBaZd6FmLuWnd3IBehnFDoQS4So=\r
+\r
+Name: org/eclipse/jface/viewers/DecorationOverlayIcon.class\r
+SHA1-Digest: Y7UN+ZBMslqOwChKuTP+JVbvOCY=\r
+\r
+Name: org/eclipse/jface/preference/FontFieldEditor$4.class\r
+SHA1-Digest: HOPmvZNPfrdPFIdmb2koHIfQVA0=\r
+\r
+Name: org/eclipse/jface/viewers/TableLayout.class\r
+SHA1-Digest: zPCs8XBBMr0ffICbyPASqKq7Uyw=\r
+\r
+Name: org/eclipse/jface/viewers/deferred/ConcurrentTableUpdator.class\r
+SHA1-Digest: OwzjHLLd/DTQ7zD5MYsfBSZYtLs=\r
+\r
+Name: org/eclipse/jface/viewers/ColumnViewerEditor$4.class\r
+SHA1-Digest: 46oxUsLbLTUc8QXl4t6S8Sd+/20=\r
+\r
+Name: org/eclipse/jface/window/ToolTip$3.class\r
+SHA1-Digest: Or+4UVtfOW2WSAYqLhNwF34+jlE=\r
+\r
+Name: org/eclipse/jface/preference/StringFieldEditor$3.class\r
+SHA1-Digest: Z2Tzj8/yEyrrbi1uk/RnOOGx5Os=\r
+\r
+Name: org/eclipse/jface/fieldassist/FieldAssistColors.class\r
+SHA1-Digest: 6O3TNVYciymrfLYWCrbX1TopUUY=\r
+\r
+Name: org/eclipse/jface/viewers/ISelection.class\r
+SHA1-Digest: v6qu+ZFiiJ/B7ag5Te3pBK19BHQ=\r
+\r
+Name: org/eclipse/jface/viewers/TreePath.class\r
+SHA1-Digest: qM2oISuX8yH+BaKH7B4KZNWfUVU=\r
+\r
+Name: org/eclipse/jface/viewers/TreeViewer$5.class\r
+SHA1-Digest: Isq93suZbPTe+8u6BYsK6J9rZ5E=\r
+\r
+Name: org/eclipse/jface/viewers/IElementComparer.class\r
+SHA1-Digest: sOaZtvS4AB/hqgZ5D1RIsBJ6lyI=\r
+\r
+Name: org/eclipse/jface/layout/TreeColumnLayout.class\r
+SHA1-Digest: x+0oz+CX28DxveiHNLcH8z2PSp8=\r
+\r
+Name: org/eclipse/jface/action/SubContributionManager$1.class\r
+SHA1-Digest: y2osOkOKwIUm8er1pBR708XDBHQ=\r
+\r
+Name: org/eclipse/jface/viewers/ColumnViewerEditorActivationListener.c\r
+ lass\r
+SHA1-Digest: bZzW8WEagCO4g5LGt7gAdKv4fok=\r
+\r
+Name: org/eclipse/jface/window/DefaultToolTip.class\r
+SHA1-Digest: vWYCKbbRk7vky9sv4+XyuNzoBsM=\r
+\r
+Name: org/eclipse/jface/util/Geometry.class\r
+SHA1-Digest: NOSckiiUmNQhIY4uV5Wdzgt7Pl8=\r
+\r
+Name: org/eclipse/jface/resource/DeviceResourceManager.class\r
+SHA1-Digest: K0fl0ke6tO8VbENziK6aQ3L60Ok=\r
+\r
+Name: org/eclipse/jface/preference/PreferenceDialog$PageLayout.class\r
+SHA1-Digest: hgPfD3IdU0KAPdn/+v+qs+JNL7k=\r
+\r
+Name: org/eclipse/jface/action/ExternalActionManager$IBindingManagerCa\r
+ llback.class\r
+SHA1-Digest: ltqW2wL1ugLf4e22Vauu7bLzGNI=\r
+\r
+Name: org/eclipse/jface/viewers/DialogCellEditor.class\r
+SHA1-Digest: H6RNBVJwdHT0CD1AvM1h49Pgjpk=\r
+\r
+Name: org/eclipse/jface/window/ToolTip$ToolTipOwnerControlListener.cla\r
+ ss\r
+SHA1-Digest: raTdFjdhKwG5kUAmMvx7frBvQ/c=\r
+\r
+Name: org/eclipse/jface/action/SubContributionManager.class\r
+SHA1-Digest: U5W16vpvNvo4s2TZxiaOxJEnRLY=\r
+\r
+Name: org/eclipse/jface/viewers/StructuredViewer$2.class\r
+SHA1-Digest: ULFmm/2x5DVLM76TmWuN/KHgJeM=\r
+\r
+Name: org/eclipse/jface/viewers/deferred/ChangeQueue.class\r
+SHA1-Digest: q7v2iwDl52cXjFX5aGC50Su/qtY=\r
+\r
+Name: org/eclipse/jface/fieldassist/DecoratedField$3.class\r
+SHA1-Digest: HopONxRvINGg5HdPKEvjSYTJQsk=\r
+\r
+Name: org/eclipse/jface/fieldassist/ControlDecoration$7.class\r
+SHA1-Digest: vw4W7AHZA8HlQmkK1QZH2kzNR9Q=\r
+\r
+Name: org/eclipse/jface/util/DelegatingDropAdapter$1.class\r
+SHA1-Digest: YTc8uaLSnGz/1kS97jxUqoLU5Z8=\r
+\r
+Name: org/eclipse/jface/viewers/ViewerLabel.class\r
+SHA1-Digest: RmWs07S4iNrcxmk/9vOwwJT0u1A=\r
+\r
+Name: org/eclipse/jface/bindings/keys/formatting/EmacsKeyFormatter.pro\r
+ perties\r
+SHA1-Digest: f2Wrkiulg1IixjoSP3f/We7gLlk=\r
+\r
+Name: org/eclipse/jface/resource/jfacefonts_windowsxp.properties\r
+SHA1-Digest: AOq+tOEd4D7kDs1EriU8ejSUBw0=\r
+\r
+Name: org/eclipse/jface/preference/RadioGroupFieldEditor$1.class\r
+SHA1-Digest: Ht+NUxZq1ltSesaqW4c5lPo97FM=\r
+\r
+Name: org/eclipse/jface/preference/ScaleFieldEditor.class\r
+SHA1-Digest: ebMXK9FL5rhpK0uhuPPsxf8V0PA=\r
+\r
+Name: org/eclipse/jface/fieldassist/images/info_ovr.gif\r
+SHA1-Digest: QOIr94zJdt1aM96T1ySsGB2diq0=\r
+\r
+Name: org/eclipse/jface/dialogs/Dialog$2.class\r
+SHA1-Digest: t1PEV5jkUDjpT+vZEIyNQ+D/t6k=\r
+\r
+Name: org/eclipse/jface/bindings/Trigger.class\r
+SHA1-Digest: ScMIxH6pA8H2s/qpnZ4RStKqm4A=\r
+\r
+Name: org/eclipse/jface/preference/PreferenceDialog$9.class\r
+SHA1-Digest: 9CysviQ86AJCcrzyR3RsHVNtdLo=\r
+\r
+Name: org/eclipse/jface/action/StatusLine$1.class\r
+SHA1-Digest: 1eNlUkuGlgioHpas3+yLSCNIKwY=\r
+\r
+Name: org/eclipse/jface/dialogs/ErrorDialog.class\r
+SHA1-Digest: enTlYXi3qDaY12njhet+QCoewqc=\r
+\r
+Name: org/eclipse/jface/viewers/ColumnViewer.class\r
+SHA1-Digest: 1lrwGiVxUTZvXpYovewE8JppR50=\r
+\r
+Name: org/eclipse/jface/layout/GridDataFactory.class\r
+SHA1-Digest: ZNJ6USDgac1ey4OzFI3Nq1YEmW0=\r
+\r
+Name: org/eclipse/jface/dialogs/IPageChangedListener.class\r
+SHA1-Digest: 8B3Te8gqEOgUJWN6ZTxIpy+Vfu8=\r
+\r
+Name: org/eclipse/jface/wizard/WizardDialog$5.class\r
+SHA1-Digest: bD3ABgsmJGNBiIQoJm7/hkm834I=\r
+\r
+Name: org/eclipse/jface/preference/PreferenceDialog$14.class\r
+SHA1-Digest: 32dZRx1+iJRASSKriotmgOQdURc=\r
+\r
+Name: org/eclipse/jface/viewers/TreePathViewerSorter.class\r
+SHA1-Digest: T+cz5sTsuNx8icLNrEIwlt2QOj4=\r
+\r
+Name: org/eclipse/jface/viewers/CellEditor$4.class\r
+SHA1-Digest: dFe4RhMEFxg4EY5y9W3Z+/loc8g=\r
+\r
+Name: org/eclipse/jface/dialogs/PopupDialog$4.class\r
+SHA1-Digest: +xnp7OGFdUnmUUM/AWMp2p8ly68=\r
+\r
+Name: org/eclipse/jface/dialogs/AnimatorFactory.class\r
+SHA1-Digest: YCT0EGjeUbg8jYcm8shnbDGsW8Q=\r
+\r
+Name: org/eclipse/jface/viewers/ComboBoxCellEditor$3.class\r
+SHA1-Digest: vkM9PvZ4rF9F/wo2GzgYzOYydH4=\r
+\r
+Name: org/eclipse/jface/viewers/OwnerDrawLabelProvider$1.class\r
+SHA1-Digest: rXBeIfEAbZt/agUC5qCogBQT1As=\r
+\r
+Name: org/eclipse/jface/viewers/ICellEditorValidator.class\r
+SHA1-Digest: ghG+8bfz08dZdRU29KWTaHI/Rjw=\r
+\r
+Name: org/eclipse/jface/bindings/keys/KeyStroke.class\r
+SHA1-Digest: xcTPBRotDFWyjD8BNgymKE2gS+Y=\r
+\r
+Name: org/eclipse/jface/bindings/keys/KeyBinding.class\r
+SHA1-Digest: kwvTdtSvRi+QnHqhh4fmIlZIyGE=\r
+\r
+Name: org/eclipse/jface/fieldassist/FieldAssistColors$1.class\r
+SHA1-Digest: TXyAp8d6WU00E1wJMO2BeGAa/Ck=\r
+\r
+Name: org/eclipse/jface/dialogs/ErrorSupportProvider.class\r
+SHA1-Digest: gvaYXsWvVx/66U1KDxG7mZv9TV4=\r
+\r
+Name: org/eclipse/jface/dialogs/MessageDialogWithToggle$1.class\r
+SHA1-Digest: OcOo7ww80O+jNlWfO8kJSoX/bmY=\r
+\r
+Name: org/eclipse/jface/viewers/DecorationContext.class\r
+SHA1-Digest: hGnn7RBTdKb3jxicuGW5ioH3rQk=\r
+\r
+Name: org/eclipse/jface/viewers/ComboBoxCellEditor.class\r
+SHA1-Digest: kgR5uSqCR6xLG6o46EDT5PxLadY=\r
+\r
+Name: org/eclipse/jface/resource/JFaceResources$1.class\r
+SHA1-Digest: Dj7mbHmRa6ff5Plfw8Vr7qPnUB8=\r
+\r
+Name: org/eclipse/jface/viewers/AbstractTableViewer$VirtualManager.cla\r
+ ss\r
+SHA1-Digest: VsUK9MANZr6j1KV9du+/kmE9pis=\r
+\r
+Name: org/eclipse/jface/preference/IPreferenceNode.class\r
+SHA1-Digest: 8tRoUpdBxtXH37yYHrB0B0E8mkY=\r
+\r
+Name: org/eclipse/jface/dialogs/TrayDialog$4.class\r
+SHA1-Digest: 8RyiTidCFwaxF0gH+BJ7WEdVJ7U=\r
+\r
+Name: org/eclipse/jface/action/images/stop.gif\r
+SHA1-Digest: BPcRKHh123ukCk1ZIcRxysDWb3Y=\r
+\r
+Name: org/eclipse/jface/viewers/TreeExpansionEvent.class\r
+SHA1-Digest: dxgpuR+QbjaE0xBNYuiCaOBkB0o=\r
+\r
+Name: org/eclipse/jface/dialogs/IDialogPage.class\r
+SHA1-Digest: rBVidzUUL1Qu/Ro2KSkJ16brX0A=\r
+\r
+Name: org/eclipse/jface/bindings/keys/formatting/IKeyFormatter.class\r
+SHA1-Digest: Uy80BmGwT0KCWMkZ1gdTijPn77A=\r
+\r
+Name: org/eclipse/jface/util/OpenStrategy$3.class\r
+SHA1-Digest: q+71OFHnpsmqfZwQpr+lveNVKeE=\r
+\r
+Name: org/eclipse/jface/fieldassist/ContentProposalAdapter$6.class\r
+SHA1-Digest: 6m+z82N0vDfXlV496kFa6qa8FIg=\r
+\r
+Name: org/eclipse/jface/viewers/ColumnViewerToolTipSupport.class\r
+SHA1-Digest: dYhZ6C6DNlIasK5ii//RWXk7FT4=\r
+\r
+Name: org/eclipse/jface/preference/StringButtonFieldEditor$2.class\r
+SHA1-Digest: so+QwMmBgkGvU/GbGvFaZe1wA9o=\r
+\r
+Name: org/eclipse/jface/window/WindowManager.class\r
+SHA1-Digest: Ti8XgX1pgBG7tLPHFVKPA4WcpRo=\r
+\r
+Name: org/eclipse/jface/resource/jfacefonts_qnx.properties\r
+SHA1-Digest: 1XnKDbwb/W15J/0x9HL752KjFIA=\r
+\r
+Name: org/eclipse/jface/viewers/deferred/LazySortedCollection.class\r
+SHA1-Digest: 6NhclZEGF0+Rs69muBm13BJXTMw=\r
+\r
diff --git a/Annotation/META-INF/MANIFEST.MF b/Annotation/META-INF/MANIFEST.MF
new file mode 100644 (file)
index 0000000..3a4ab9d
--- /dev/null
@@ -0,0 +1,4 @@
+Manifest-Version: 1.0\r
+Ant-Version: Apache Ant 1.7.1\r
+Created-By: 10.0-b23 (Sun Microsystems Inc.)\r
+\r
diff --git a/Annotation/META-INF/eclipse.inf b/Annotation/META-INF/eclipse.inf
new file mode 100644 (file)
index 0000000..7864d3c
--- /dev/null
@@ -0,0 +1,3 @@
+#Processed using Jarprocessor
+pack200.args = -E4
+pack200.conditioned = true
diff --git a/Annotation/about.html b/Annotation/about.html
new file mode 100644 (file)
index 0000000..4602330
--- /dev/null
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+<p>June 2, 2006</p>    
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;).  Unless otherwise 
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;).  A copy of the EPL is available 
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is 
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content.  Check the Redistributor's license that was 
+provided with the Content.  If no such license exists, contact the Redistributor.  Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/Annotation/external.xpt b/Annotation/external.xpt
new file mode 100644 (file)
index 0000000..f57da7e
Binary files /dev/null and b/Annotation/external.xpt differ
diff --git a/Annotation/plugin.properties b/Annotation/plugin.properties
new file mode 100644 (file)
index 0000000..528303e
--- /dev/null
@@ -0,0 +1,12 @@
+###############################################################################
+# Copyright (c) 2000, 2005 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+pluginName = JFace
+providerName = Eclipse.org
diff --git a/Annotation/plugins/BPTPlugin.plugin/bptplugin.jar b/Annotation/plugins/BPTPlugin.plugin/bptplugin.jar
new file mode 100644 (file)
index 0000000..d4025cf
Binary files /dev/null and b/Annotation/plugins/BPTPlugin.plugin/bptplugin.jar differ
diff --git a/Annotation/plugins/BPTPlugin.plugin/jbpt.dll b/Annotation/plugins/BPTPlugin.plugin/jbpt.dll
new file mode 100644 (file)
index 0000000..d12f777
Binary files /dev/null and b/Annotation/plugins/BPTPlugin.plugin/jbpt.dll differ
diff --git a/Annotation/plugins/BPTPlugin.plugin/libjbpt.jnilib b/Annotation/plugins/BPTPlugin.plugin/libjbpt.jnilib
new file mode 100644 (file)
index 0000000..77039d7
Binary files /dev/null and b/Annotation/plugins/BPTPlugin.plugin/libjbpt.jnilib differ
diff --git a/Annotation/plugins/BPTPlugin.plugin/libjbpt.so b/Annotation/plugins/BPTPlugin.plugin/libjbpt.so
new file mode 100644 (file)
index 0000000..5b69c7d
Binary files /dev/null and b/Annotation/plugins/BPTPlugin.plugin/libjbpt.so differ
diff --git a/Annotation/plugins/BPTPlugin.plugin/libjbpt64.so b/Annotation/plugins/BPTPlugin.plugin/libjbpt64.so
new file mode 100644 (file)
index 0000000..998a3d4
Binary files /dev/null and b/Annotation/plugins/BPTPlugin.plugin/libjbpt64.so differ
diff --git a/Annotation/plugins/BPTPlugin.plugin/plugin.xml b/Annotation/plugins/BPTPlugin.plugin/plugin.xml
new file mode 100644 (file)
index 0000000..4ae529d
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<plugin>
+       <meta name="name" value="BPT Plugin" />
+       <meta name="description" value="Binary Partition Tree Plugin" />
+       <meta name="vendor" value="Dublin City University" />
+       <meta name="author" value="Kevin McGuinness" />
+       <meta name="email" value="kevin.mcguinness@gmail.com" />
+       <meta name="segmenter" value="ie.dcu.segment.algorithm.BptSegmenter" /> 
+       <jar file="bptplugin.jar" />
+</plugin>
diff --git a/Annotation/plugins/IGCPlugin.plugin/igcplugin.jar b/Annotation/plugins/IGCPlugin.plugin/igcplugin.jar
new file mode 100644 (file)
index 0000000..c85393b
Binary files /dev/null and b/Annotation/plugins/IGCPlugin.plugin/igcplugin.jar differ
diff --git a/Annotation/plugins/IGCPlugin.plugin/jigc.dll b/Annotation/plugins/IGCPlugin.plugin/jigc.dll
new file mode 100644 (file)
index 0000000..b4ee98c
Binary files /dev/null and b/Annotation/plugins/IGCPlugin.plugin/jigc.dll differ
diff --git a/Annotation/plugins/IGCPlugin.plugin/libjigc.jnilib b/Annotation/plugins/IGCPlugin.plugin/libjigc.jnilib
new file mode 100644 (file)
index 0000000..6ff9817
Binary files /dev/null and b/Annotation/plugins/IGCPlugin.plugin/libjigc.jnilib differ
diff --git a/Annotation/plugins/IGCPlugin.plugin/libjigc.so b/Annotation/plugins/IGCPlugin.plugin/libjigc.so
new file mode 100644 (file)
index 0000000..926f242
Binary files /dev/null and b/Annotation/plugins/IGCPlugin.plugin/libjigc.so differ
diff --git a/Annotation/plugins/IGCPlugin.plugin/libjigc64.so b/Annotation/plugins/IGCPlugin.plugin/libjigc64.so
new file mode 100644 (file)
index 0000000..e7a71b3
Binary files /dev/null and b/Annotation/plugins/IGCPlugin.plugin/libjigc64.so differ
diff --git a/Annotation/plugins/IGCPlugin.plugin/plugin.xml b/Annotation/plugins/IGCPlugin.plugin/plugin.xml
new file mode 100644 (file)
index 0000000..2b7ae2e
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<plugin>
+       <meta name="name" value="IGC Plugin" />
+       <meta name="description" value="Interactive Graph Cuts Plugin" />
+       <meta name="vendor" value="Dublin City University" />
+       <meta name="author" value="Kevin McGuinness" />
+       <meta name="email" value="kevin.mcguinness@gmail.com" />
+       <meta name="segmenter" value="ie.dcu.segment.algorithm.IgcSegmenter" /> 
+       <jar file="igcplugin.jar" />
+</plugin>
diff --git a/Annotation/plugins/SIOXPlugin.plugin/plugin.xml b/Annotation/plugins/SIOXPlugin.plugin/plugin.xml
new file mode 100644 (file)
index 0000000..623ad7b
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<plugin>
+       <meta name="name" value="SIOX Plugin" />
+       <meta name="description" value="Simple Interactive Object Extraction Plugin" />
+       <meta name="vendor" value="Dublin City University" />
+       <meta name="author" value="Kevin McGuinness" />
+       <meta name="email" value="kevin.mcguinness@gmail.com" />
+       <meta name="segmenter" value="ie.dcu.segment.algorithm.SioxSegmenter" />        
+       <jar file="sioxplugin.jar" />
+       <jar file="sioxapi.jar" />
+</plugin>
diff --git a/Annotation/plugins/SIOXPlugin.plugin/sioxapi.jar b/Annotation/plugins/SIOXPlugin.plugin/sioxapi.jar
new file mode 100644 (file)
index 0000000..4c121b2
Binary files /dev/null and b/Annotation/plugins/SIOXPlugin.plugin/sioxapi.jar differ
diff --git a/Annotation/plugins/SIOXPlugin.plugin/sioxplugin.jar b/Annotation/plugins/SIOXPlugin.plugin/sioxplugin.jar
new file mode 100644 (file)
index 0000000..31f959a
Binary files /dev/null and b/Annotation/plugins/SIOXPlugin.plugin/sioxplugin.jar differ
diff --git a/Annotation/plugins/SRGPlugin.plugin/jsrg.dll b/Annotation/plugins/SRGPlugin.plugin/jsrg.dll
new file mode 100644 (file)
index 0000000..c381fae
Binary files /dev/null and b/Annotation/plugins/SRGPlugin.plugin/jsrg.dll differ
diff --git a/Annotation/plugins/SRGPlugin.plugin/libjsrg.jnilib b/Annotation/plugins/SRGPlugin.plugin/libjsrg.jnilib
new file mode 100644 (file)
index 0000000..46427e8
Binary files /dev/null and b/Annotation/plugins/SRGPlugin.plugin/libjsrg.jnilib differ
diff --git a/Annotation/plugins/SRGPlugin.plugin/libjsrg.so b/Annotation/plugins/SRGPlugin.plugin/libjsrg.so
new file mode 100644 (file)
index 0000000..c44f5af
Binary files /dev/null and b/Annotation/plugins/SRGPlugin.plugin/libjsrg.so differ
diff --git a/Annotation/plugins/SRGPlugin.plugin/libjsrg64.so b/Annotation/plugins/SRGPlugin.plugin/libjsrg64.so
new file mode 100644 (file)
index 0000000..65cb9f7
Binary files /dev/null and b/Annotation/plugins/SRGPlugin.plugin/libjsrg64.so differ
diff --git a/Annotation/plugins/SRGPlugin.plugin/plugin.xml b/Annotation/plugins/SRGPlugin.plugin/plugin.xml
new file mode 100644 (file)
index 0000000..4061f98
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<plugin>
+       <meta name="name" value="SRG Plugin" />
+       <meta name="description" value="Seeded Region Growing Plugin" />
+       <meta name="vendor" value="Dublin City University" />
+       <meta name="author" value="Kevin McGuinness" />
+       <meta name="email" value="kevin.mcguinness@gmail.com" />
+       <meta name="segmenter" value="ie.dcu.segment.algorithm.SrgSegmenter" /> 
+       <jar file="srgplugin.jar" />
+</plugin>
diff --git a/Annotation/plugins/SRGPlugin.plugin/srgplugin.jar b/Annotation/plugins/SRGPlugin.plugin/srgplugin.jar
new file mode 100644 (file)
index 0000000..c888c62
Binary files /dev/null and b/Annotation/plugins/SRGPlugin.plugin/srgplugin.jar differ
diff --git a/Annotation/resources/ant/lib/ant-deb.jar b/Annotation/resources/ant/lib/ant-deb.jar
new file mode 100644 (file)
index 0000000..f602bec
Binary files /dev/null and b/Annotation/resources/ant/lib/ant-deb.jar differ
diff --git a/Annotation/resources/ant/lib/ant-gzip2.jar b/Annotation/resources/ant/lib/ant-gzip2.jar
new file mode 100644 (file)
index 0000000..271f123
Binary files /dev/null and b/Annotation/resources/ant/lib/ant-gzip2.jar differ
diff --git a/Annotation/resources/ant/lib/ant-passwd-task.jar b/Annotation/resources/ant/lib/ant-passwd-task.jar
new file mode 100644 (file)
index 0000000..b4f4b76
Binary files /dev/null and b/Annotation/resources/ant/lib/ant-passwd-task.jar differ
diff --git a/Annotation/resources/ant/lib/ant-swt-identify.jar b/Annotation/resources/ant/lib/ant-swt-identify.jar
new file mode 100644 (file)
index 0000000..daddc1c
Binary files /dev/null and b/Annotation/resources/ant/lib/ant-swt-identify.jar differ
diff --git a/Annotation/resources/ant/lib/jsmoothgen-ant.jar b/Annotation/resources/ant/lib/jsmoothgen-ant.jar
new file mode 100644 (file)
index 0000000..c9e283d
Binary files /dev/null and b/Annotation/resources/ant/lib/jsmoothgen-ant.jar differ
diff --git a/Annotation/resources/ant/lib/standalone-compiler.jar b/Annotation/resources/ant/lib/standalone-compiler.jar
new file mode 100644 (file)
index 0000000..2762975
Binary files /dev/null and b/Annotation/resources/ant/lib/standalone-compiler.jar differ
diff --git a/Annotation/resources/ant/properties b/Annotation/resources/ant/properties
new file mode 100644 (file)
index 0000000..38b429c
--- /dev/null
@@ -0,0 +1,14 @@
+app.name=Interactive Segmentation Tool
+app.package=ist
+app.version=1.3.4
+app.author=Kevin McGuinness
+app.email=kevin.mcguinness@eeng.dcu.ie
+app.website=http://kspace.cdvp.dcu.ie/public/interactive-segmentation
+app.synopsis=The CDVP Interactive Segmentation Tool
+app.main=ie.dcu.apps.ist.Main
+
+# Compilation properties
+java.debug=off
+java.source.version=1.5
+java.target.version=1.5
+
diff --git a/Annotation/resources/config/actions.mac.properties b/Annotation/resources/config/actions.mac.properties
new file mode 100644 (file)
index 0000000..8a282fa
--- /dev/null
@@ -0,0 +1,108 @@
+
+OpenAction.dialog.text=Open an image or saved context
+OpenAction.dialog.filter.exts=*.jpg;*.jpeg;*.png;*.gif;*.bmp;*.ctx
+OpenAction.dialog.filter.text=Image and Context Files
+
+SaveAction.dialog.text=Save Segmentation Context
+SaveAction.dialog.filter.exts=*.ctx
+SaveAction.dialog.filter.text=Segmentation Context Files
+
+ExportViewAction.dialog.text=Export View As Image
+ExportViewAction.dialog.filter.exts=*.jpg;*.jpeg;*.png;*.gif;*.bmp;
+ExportViewAction.dialog.filter.text=Image Files
+
+OpenExperimentAction.dialog.text=Open an experiment file
+OpenExperimentAction.dialog.filter.exts=*.exp
+OpenExperimentAction.dialog.filter.text=Experiment Files
+
+# Actions
+action.OpenAction.text=&Open...@Command+O
+action.OpenAction.image=file:resources/icons/open.png
+action.OpenAction.tooltip=Open image
+
+action.SaveAction.text=&Save@Command+S
+action.SaveAction.image=file:resources/icons/save.png
+action.SaveAction.tooltip=Save segmentation context
+
+action.SaveAsAction.text=S&ave As...@Command+Shift+S
+action.SaveAsAction.image=file:resources/icons/save-as.png
+action.SaveAsAction.tooltip=Save segmentation context as...
+
+action.ExportViewAction.text=&Current View...@Command+Alt+V
+action.ExportViewAction.image=file:resources/icons/image.png
+action.ExportViewAction.tooltip=Export view as image
+
+action.ExportImageMapAction.text=&HTML Image Map...@Command+Alt+H
+action.ExportImageMapAction.image=file:resources/icons/html.png
+action.ExportImageMapAction.tooltip=Export objects as HTML image map
+
+action.ExportTransparentPNGAction.text=Export Transparent &PNG...@Command+Alt+P
+action.ExportTransparentPNGAction.image=file:resources/icons/image.png
+action.ExportTransparentPNGAction.tooltip=Export a PNG of the current segmentation with a transparent background
+
+action.ImportAction.text=&Import...
+action.ImportAction.image=file:resources/icons/import.png
+action.ImportAction.tooltip=Import images
+
+action.PrintAction.text=&Print@Command+P
+action.PrintAction.image=file:resources/icons/print.png
+action.PrintAction.tooltip=Print view
+
+action.ExitAction.text=E&xit@Command+Q
+action.ExitAction.image=file:resources/icons/exit.png
+action.ExitAction.tooltip=Quit the application
+
+action.UndoAction.text=&Undo@Command+Z
+action.UndoAction.image=file:resources/icons/undo.png
+action.UndoAction.tooltip=Undo last markup
+
+action.RedoAction.text=&Redo@Command+Y
+action.RedoAction.image=file:resources/icons/redo.png
+action.RedoAction.tooltip=Redo markup
+
+action.CopyAction.text=&Copy@Command+C
+action.CopyAction.image=file:resources/icons/copy.png
+action.CopyAction.tooltip=Copy view to clipboard as image
+
+action.PreferencesAction.text=&Preferences...@Command+,
+action.PreferencesAction.image=file:resources/icons/preferences.png
+action.PreferencesAction.tooltip=Change application settings
+
+action.AddFilesAction.text=&Add Files...@Command+A
+action.AddFilesAction.image=file:resources/icons/add.png
+action.AddFilesAction.tooltip=Add image files to project
+
+action.RemoveFilesAction.text=&Remove Files@Command+R
+action.RemoveFilesAction.image=file:resources/icons/remove.png
+action.RemoveFilesAction.tooltip=Remove selected image files from project
+
+action.PreviousAction.text=&Previous@Command+[
+action.PreviousAction.image=file:resources/icons/previous.png
+action.PreviousAction.tooltip=Move to previous image in directory
+
+action.NextAction.text=&Next@Command+]
+action.NextAction.image=file:resources/icons/next.png
+action.NextAction.tooltip=Move to next image in directory
+
+action.HelpAction.text=&Help Contents...@Command+F1
+action.HelpAction.image=file:resources/icons/help.png
+action.HelpAction.tooltip=Show application help browser
+action.HelpAction.helpURL=http://kspace.cdvp.dcu.ie/public/interactive-segmentation/doc/help.html
+
+action.AboutAction.text=&About...
+action.AboutAction.image=file:resources/icons/about.png
+action.AboutAction.tooltip=About the application
+action.AboutAction.aboutImage=file:resources/icons/about-box.png
+
+action.OpenExperimentAction.text=Open &Experiment...
+action.OpenExperimentAction.image=file:resources/icons/experiment.png
+action.OpenExperimentAction.tooltip=Open an experiment file and switch to experiment mode
+
+action.ConfigureSegmenterAction.text=&Configure Segmenter...@Command+Shift+C
+action.ConfigureSegmenterAction.image=file:resources/icons/preferences.png
+action.ConfigureSegmenterAction.tooltip=Configure segmenter parameters
+
+action.SelectSegmenterAction.NA=Algorithm not available on this platform
+
+
+
diff --git a/Annotation/resources/config/actions.properties b/Annotation/resources/config/actions.properties
new file mode 100644 (file)
index 0000000..f2ddcb0
--- /dev/null
@@ -0,0 +1,106 @@
+
+OpenAction.dialog.text=Open an image or saved context
+OpenAction.dialog.filter.exts=*.jpg;*.jpeg;*.png;*.gif;*.bmp;*.ctx
+OpenAction.dialog.filter.text=Image and Context Files
+
+SaveAction.dialog.text=Save Segmentation Context
+SaveAction.dialog.filter.exts=*.ctx
+SaveAction.dialog.filter.text=Segmentation Context Files
+
+ExportViewAction.dialog.text=Export View As Image
+ExportViewAction.dialog.filter.exts=*.jpg;*.jpeg;*.png;*.gif;*.bmp;
+ExportViewAction.dialog.filter.text=Image Files
+
+OpenExperimentAction.dialog.text=Open an experiment file
+OpenExperimentAction.dialog.filter.exts=*.exp
+OpenExperimentAction.dialog.filter.text=Experiment Files
+
+# Actions
+action.OpenAction.text=&Open...@Ctrl+O
+action.OpenAction.image=file:resources/icons/open.png
+action.OpenAction.tooltip=Open image
+
+action.SaveAction.text=&Save@Ctrl+S
+action.SaveAction.image=file:resources/icons/save.png
+action.SaveAction.tooltip=Save segmentation context
+
+action.SaveAsAction.text=S&ave As...@Ctrl+Shift+S
+action.SaveAsAction.image=file:resources/icons/save-as.png
+action.SaveAsAction.tooltip=Save segmentation context as...
+
+action.ExportViewAction.text=&Current View...@Ctrl+Shift+V
+action.ExportViewAction.image=file:resources/icons/image.png
+action.ExportViewAction.tooltip=Export view as image
+
+action.ExportImageMapAction.text=&HTML Image Map...@Ctrl+Shift+H
+action.ExportImageMapAction.image=file:resources/icons/html.png
+action.ExportImageMapAction.tooltip=Export objects as HTML image map
+
+action.ExportTransparentPNGAction.text=Export Transparent &PNG...@Ctrl+Shift+P
+action.ExportTransparentPNGAction.image=file:resources/icons/image.png
+action.ExportTransparentPNGAction.tooltip=Export a PNG of the current segmentation with a transparent background
+
+
+action.ImportAction.text=&Import...
+action.ImportAction.image=file:resources/icons/import.png
+action.ImportAction.tooltip=Import images
+
+action.PrintAction.text=&Print@Ctrl+P
+action.PrintAction.image=file:resources/icons/print.png
+action.PrintAction.tooltip=Print view
+
+action.ExitAction.text=E&xit@Ctrl+Q
+action.ExitAction.image=file:resources/icons/exit.png
+action.ExitAction.tooltip=Quit the application
+
+action.UndoAction.text=&Undo@Ctrl+Z
+action.UndoAction.image=file:resources/icons/undo.png
+action.UndoAction.tooltip=Undo last markup
+
+action.RedoAction.text=&Redo@Ctrl+Y
+action.RedoAction.image=file:resources/icons/redo.png
+action.RedoAction.tooltip=Redo markup
+
+action.CopyAction.text=&Copy@Ctrl+C
+action.CopyAction.image=file:resources/icons/copy.png
+action.CopyAction.tooltip=Copy view to clipboard as image
+
+action.PreferencesAction.text=&Preferences...
+action.PreferencesAction.image=file:resources/icons/preferences.png
+action.PreferencesAction.tooltip=Change application settings
+
+action.AddFilesAction.text=&Add Files...@Ctrl+A
+action.AddFilesAction.image=file:resources/icons/add.png
+action.AddFilesAction.tooltip=Add image files to project
+
+action.RemoveFilesAction.text=&Remove Files@Ctrl+R
+action.RemoveFilesAction.image=file:resources/icons/remove.png
+action.RemoveFilesAction.tooltip=Remove selected image files from project
+
+action.PreviousAction.text=&Previous@Ctrl+[
+action.PreviousAction.image=file:resources/icons/previous.png
+action.PreviousAction.tooltip=Move to previous image in directory
+
+action.NextAction.text=&Next@Ctrl+]
+action.NextAction.image=file:resources/icons/next.png
+action.NextAction.tooltip=Move to next image in directory
+
+action.HelpAction.text=&Help Contents...@Ctrl+F1
+action.HelpAction.image=file:resources/icons/help.png
+action.HelpAction.tooltip=Show application help browser
+action.HelpAction.helpURL=http://kspace.cdvp.dcu.ie/public/interactive-segmentation/doc/help.html
+
+action.AboutAction.text=&About...
+action.AboutAction.image=file:resources/icons/about.png
+action.AboutAction.tooltip=About the application
+action.AboutAction.aboutImage=file:resources/icons/about-box.png
+
+action.OpenExperimentAction.text=Open &Experiment...
+action.OpenExperimentAction.image=file:resources/icons/experiment.png
+action.OpenExperimentAction.tooltip=Open an experiment file and switch to experiment mode
+
+action.ConfigureSegmenterAction.text=&Configure Segmenter...@Ctrl+Shift+C
+action.ConfigureSegmenterAction.image=file:resources/icons/preferences.png
+action.ConfigureSegmenterAction.tooltip=Configure segmenter parameters
+
+action.SelectSegmenterAction.NA=Algorithm not available on this platform
diff --git a/Annotation/resources/config/application.mac.properties b/Annotation/resources/config/application.mac.properties
new file mode 100644 (file)
index 0000000..096ea68
--- /dev/null
@@ -0,0 +1,25 @@
+
+AppRecentMenu.icon=file:resources/icons/open-recent.png
+ExportMenu.icon=file:resources/icons/export.png
+
+# Preferences Dialog
+PrefsDialog.title=Preferences
+PrefsDialog.application=Application
+PrefsDialog.status=Status Area
+PrefsDialog.view=View Preferences
+PrefsDialog.experiment=Experiment Mode
+PrefsDialog.general.tab=General
+PrefsDialog.close.text=&Close
+PrefsDialog.reset.text=&Reset
+PrefsDialog.enable-feedback.text=Show position and color in the status area
+PrefsDialog.foreground-color.text=Foreground color for markup
+PrefsDialog.background-color.text=Background color for markup
+PrefsDialog.experiment-embedded.text=Show experiment panel embedded in main window
+PrefsDialog.confirm-exit.text=Confirm exit when application is closed
+
+# Experiment Panel
+ExperimentPanel.description.title=Task Description 
+ExperimentPanel.timeout-message=The time allocated for this task is up!
+ExperimentPanel.experiment-complete-message=The experiment has been completed
+ExperimentPanel.button.text.start=Start
+ExperimentPanel.button.text.finish=Finish
diff --git a/Annotation/resources/config/application.properties b/Annotation/resources/config/application.properties
new file mode 100644 (file)
index 0000000..d21c608
--- /dev/null
@@ -0,0 +1,27 @@
+
+AppRecentMenu.icon=file:resources/icons/open-recent.png
+ExportMenu.icon=file:resources/icons/export.png
+
+# Preferences Dialog
+PrefsDialog.title=Preferences
+PrefsDialog.application=Application
+PrefsDialog.status=Status Area
+PrefsDialog.view=View Preferences
+PrefsDialog.experiment=Experiment Mode
+PrefsDialog.general.tab=General
+PrefsDialog.close.text=&Close
+PrefsDialog.close.icon=file:resources/icons/close.png
+PrefsDialog.reset.text=&Reset
+PrefsDialog.reset.icon=file:resources/icons/reset.png
+PrefsDialog.enable-feedback.text=Show position and color in the status area
+PrefsDialog.foreground-color.text=Foreground color for markup
+PrefsDialog.background-color.text=Background color for markup
+PrefsDialog.experiment-embedded.text=Show experiment panel embedded in main window
+PrefsDialog.confirm-exit.text=Confirm exit when application is closed
+
+# Experiment Panel
+ExperimentPanel.description.title=Task Description 
+ExperimentPanel.timeout-message=The time allocated for this task is up!
+ExperimentPanel.experiment-complete-message=The experiment has been completed
+ExperimentPanel.button.text.start=Start
+ExperimentPanel.button.text.finish=Finish
diff --git a/Annotation/resources/config/view.properties b/Annotation/resources/config/view.properties
new file mode 100644 (file)
index 0000000..73be3a2
--- /dev/null
@@ -0,0 +1,49 @@
+SegmentationView.Action.Foreground.text=Markup Foreground
+SegmentationView.Action.Foreground.tooltip=Markup Foreground Pixels
+SegmentationView.Action.Foreground.image=file:resources/icons/foreground.png
+SegmentationView.Action.Background.text=Markup Background
+SegmentationView.Action.Background.tooltip=Markup Background Pixels
+SegmentationView.Action.Background.image=file:resources/icons/background.png
+SegmentationView.Action.ZoomIn.text=Zoom In
+SegmentationView.Action.ZoomIn.tooltip=Zoom In
+SegmentationView.Action.ZoomIn.image=file:resources/icons/zoom-in.png
+SegmentationView.Action.ZoomOut.text=Zoom Out
+SegmentationView.Action.ZoomOut.tooltip=Zoom Out
+SegmentationView.Action.ZoomOut.image=file:resources/icons/zoom-out.png
+SegmentationView.Action.ZoomOriginal.text=Zoom Original
+SegmentationView.Action.ZoomOriginal.tooltip=Zoom to Original Size
+SegmentationView.Action.ZoomOriginal.image=file:resources/icons/zoom-original.png
+SegmentationView.Action.ZoomBestFit.text=Zoom Best Fit
+SegmentationView.Action.ZoomBestFit.tooltip=Zoom to Best Fit
+SegmentationView.Action.ZoomBestFit.image=file:resources/icons/zoom-best-fit.png
+SegmentationView.Action.Repaint.text=Refresh
+SegmentationView.Action.Repaint.tooltip=Refresh and repaint view
+SegmentationView.Action.Repaint.image=file:resources/icons/refresh.png
+SegmentationView.Action.Undo.text=&Undo@Ctrl+Z
+SegmentationView.Action.Undo.tooltip=Undo last markup
+SegmentationView.Action.Undo.image=file:resources/icons/undo.png
+SegmentationView.Action.Redo.text=&Redo@Ctrl+Y
+SegmentationView.Action.Redo.tooltip=Redo markup
+SegmentationView.Action.Redo.image=file:resources/icons/redo.png
+SegmentationView.Action.Clear.text=&Clear@Ctrl+DELETE
+SegmentationView.Action.Clear.tooltip=Clear all markup
+SegmentationView.Action.Clear.image=file:resources/icons/clear.png
+SegmentationView.Action.SetBrushSize.text=Set &Brush@Ctrl+B
+SegmentationView.Action.SetBrushSize.tooltip=Set the markup brush size
+SegmentationView.Action.SetBrushSize.image=file:resources/icons/brush.png
+SegmentationView.Action.AutoApply.text=Auto Segment@Ctrl+Shift+A
+SegmentationView.Action.AutoApply.tooltip=Toggle auto segment
+SegmentationView.Action.AutoApply.image=file:resources/icons/auto.png
+SegmentationView.Action.Apply.text=Segment@Ctrl+Shift+S
+SegmentationView.Action.Apply.tooltip=Apply new markup now
+SegmentationView.Action.Apply.image=file:resources/icons/apply.png
+SegmentationView.Action.SetPainter.text=View :
+SegmentationView.Action.SetPainter.tooltip=Select how to view the image/segmentation.
+SegmentationView.Action.SetPainter.image=
+SegmentationView.Action.SegmenterOptions.text=Configure Segmenter@Ctrl+Shift+C
+SegmentationView.Action.SegmenterOptions.tooltip=Configure the segmenter
+SegmentationView.Action.SegmenterOptions.image=file:resources/icons/preferences.png
+SegmentationView.Action.SetLabel.text=Annotate :
+SegmentationView.Action.SetLabel.tooltip=Annotate the segmented piece.
+SegmentationView.Action.SetLabel.image=
+
diff --git a/Annotation/resources/doc/help.html b/Annotation/resources/doc/help.html
new file mode 100644 (file)
index 0000000..44a573f
--- /dev/null
@@ -0,0 +1,169 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html><head><meta content="text/html; charset=ISO-8859-1" http-equiv="content-type"><title>Interactive Segmentation Tool - User Guide</title><style type="text/css">
+.guicommand {
+  font-family: "Courier New",Courier,monospace;
+  font-weight: normal;
+  color: #990100;
+}
+.guishortcut {
+  font-family: "Courier New",Courier,monospace;
+  color: #666666;
+  font-style: italic;
+}
+.section {
+  font-weight: bold;
+  color: #404040;
+}
+.all {
+  margin: 0px;
+  padding: 10px 15px 50px;
+  background-color: white;
+}
+body {
+  margin: 0px 10px;
+  padding: 0px;
+  border-right-width: 1px;
+  border-left-width: 1px;
+  font-family: Arial,Helvetica,sans-serif;
+  border-right-style: dotted;
+  border-left-style: dotted;
+  background-color: #eff0ea;
+}
+h1 {
+  margin: 0px;
+  border-bottom-style: solid;
+  border-bottom-width: 1px;
+  padding-top: 10px;
+  padding-bottom: 15px;
+  text-align: center;
+  color: #404040;
+}
+h2 {
+  text-align: center;
+  color: #404040;
+}
+h3 {
+  color: #404040;
+}
+li {
+  padding-bottom: 10px;
+}
+.footer {
+  font-size: x-small;
+  text-align: center;
+}
+
+</style></head>
+<body>
+<div class="all">
+<h1>Interactive Segmentation Tool</h1>
+<h2>User Guide</h2>
+<h3>Usage</h3>
+In this section I will outline how to perform typical operations using
+the tool, such as opening images, extracting objects and exporting
+segmentation masks.<br>
+<br>
+<span class="section">Open an Image</span>&nbsp;<br>
+To open an image, select <span class="guicommand">File-&gt;Open</span><span class="guishortcut"></span>. Recently open files can
+be accessed using the <span class="guicommand">File-&gt;Open
+Recent</span> menu. Alternatively, an image file can be dragged
+from your file system and dropped into the application to open it.
+Currently images of type JPEG, PNG, GIF, and BMP are supported.<br>
+<br>
+<span class="section">Select a Segmenter</span><br>
+There are several different segmenters available in the tool. These can
+be selected from the <span class="guicommand">Tools</span>
+menu<span class="guicommand"></span>. To select one,
+click on it.<br>
+<br>
+<span class="section">Segmenting the Image&nbsp;</span><br class="section">
+Once you have an image open and a segmenter selected, you can segment
+the image by drawing scribbles on the image. First, move the mouse over
+the object you want to extract. Left click and drag inside the object
+to draw some scribbles inside the object. Now, move the mouse outside
+the object to some background pixels. Using the right mouse button,
+scribble outside the object to select some background. If using Mac
+OSX, or if you do not have a right mouse button (Graphics Tablet etc),
+you can use <span style="font-family: monospace;">Ctrl</span>
+and click instead of right click.<br>
+<br>
+The image will be segmented and the foreground will be brightened and
+the background darkened. If you are not happy with the segmentation,
+you can add more foreground and background scribbles.<br>
+<br>
+<span class="section">Undo, Redo and Clear</span><br>
+If you make a mistake, it can be undone by selecting <span class="guicommand">Edit-&gt;Undo</span><span style="font-weight: bold;"><span style="font-weight: bold;"></span> </span>or
+clicking the undo <img style="width: 16px; height: 16px;" alt="Undo Button" src="icons/undo.png"> button in the
+toolbar. To redo, select <span class="guicommand">Edit-&gt;Redo&nbsp;</span><span style="font-weight: bold;"></span>or click the
+redo&nbsp;<img style="width: 16px; height: 16px;" alt="Redo Button" src="icons/redo.png"> button. To
+remove all forground and background markup, click on the clear&nbsp;<img style="width: 16px; height: 16px;" alt="Clear Button" src="icons/reset.png"> button in the toolbar.<br>
+<br>
+<span class="section">Zooming</span><br>
+To get a closer look at&nbsp;the image, the toolbar can also be
+used to zoom-in on the image. To zoom-in by 10% use the <img style="width: 16px; height: 16px;" alt="Zoom In" src="icons/zoom-in.png"> button. To zoom-out by 10% use
+the&nbsp;<img style="width: 16px; height: 16px;" alt="Zoom Out" src="icons/zoom-out.png"> button. To
+zoom the image such that it fits into the window without needing
+scrollbars, use the <img style="width: 16px; height: 16px;" alt="Zoom Best Fit" src="icons/zoom-best-fit.png">
+button. To restore the image to its original size use the <img style="width: 16px; height: 16px;" alt="Zoom Original" src="icons/zoom-original.png"> button.<br>
+<br>
+<span class="section">Brush Size</span><br>
+To change the brush size, use the <img style="width: 16px; height: 16px;" alt="Paintbrush" src="icons/brush.png"> button to show the brush size
+chooser. It is often useful to use a bigger brush to make markings more
+visible or to quickly mark up more pixels.<br>
+<br>
+<span class="section">Views</span><br>
+It is sometimes useful to view the segmentation results in different
+ways. The default selected view is called "Combined" and shows the
+image, it's segmentation highlighted and the scribbles all overlayed on
+the same image. By using the drop down menu, you can select a different
+view:<br>
+<ul>
+<li><span style="font-style: italic;">Combined</span>:
+Shows the image with foreground areas brightened and background areas
+darkened. The foreground and background scribbles are overlayed.</li>
+<li><span style="font-style: italic;">Original:</span>
+Shows the original image, without any segmentation or scribbles
+overlayed.</li>
+<li><span style="font-style: italic;">Markup:</span>
+Shows only the foreground and background markup (scribbles).</li>
+<li><span style="font-style: italic;">Mask:</span>
+Shows the segmentation mask. That is, an image such that the foreground
+area is completely white and the background area completely black.</li>
+<li><span style="font-style: italic;">Foreground
+Only:</span> Removes all background elements and displays only
+the foreground object.</li>
+<li><span style="font-style: italic;">Outline
+Overlayed: </span>Displays and outline of the object overlayed
+onto the original image.</li>
+</ul>
+<strong>Note:</strong><span style="font-weight: bold;">
+</span>Only the combined view displays the foreground and
+background markup (scribbles). So if you are wondering where the
+scribbles disappeared to, select the combined view to make them visible.<br>
+<br class="section">
+<span class="section">Saving and Exporting</span><br>
+To save an work in progress segmentation, select <span class="guicommand">File-&gt;Save</span> or <span class="guicommand">File-&gt;Save As</span>. This
+will save the current segmentation and markup as a context file (<span style="font-family: monospace;">.ctx</span>). When
+finished segmenting an image, you may want to export the view as an
+image. To export the current view select <span class="guicommand">File-&gt;Export</span>.
+For example, if you wanted to save the segmentation mask, select the
+mask view and then <span class="guicommand">File-&gt;Export</span>.
+<br>
+<br class="section">
+<span class="section">Configuring a Segmenter</span><br>
+Some segmenters have parameters and options that can are configurable.
+To configure the selected segmenter, select <span class="guicommand">Tools-&gt;Configure
+Segmenter</span>, or click the <img style="width: 16px; height: 16px;" alt="Configure" src="icons/configure.png"> button in the toolbar.<br>
+<br class="section">
+<span class="section">Navigating Directories of Images</span><br>
+To quickly jump to the next or previous image in the current directory
+(the one containing the open image), use the <span class="guicommand">Go-&gt;Next</span> and <span class="guicommand">Go-&gt;Previous</span> menu
+items.<br>
+<br>
+<span class="section">Experiments</span><br class="section">
+Experiment files can be opened using the <span class="guicommand">Tools-&gt;Open
+Experiment</span> menu item.<br><br><br>
+<div class="footer">Kevin McGuinness 2008
+</div>
+</div>
+</body></html>
\ No newline at end of file
diff --git a/Annotation/resources/icons/about-box.png b/Annotation/resources/icons/about-box.png
new file mode 100644 (file)
index 0000000..3cd2db6
Binary files /dev/null and b/Annotation/resources/icons/about-box.png differ
diff --git a/Annotation/resources/icons/about.png b/Annotation/resources/icons/about.png
new file mode 100644 (file)
index 0000000..3b8a885
Binary files /dev/null and b/Annotation/resources/icons/about.png differ
diff --git a/Annotation/resources/icons/application.png b/Annotation/resources/icons/application.png
new file mode 100644 (file)
index 0000000..ca883da
Binary files /dev/null and b/Annotation/resources/icons/application.png differ
diff --git a/Annotation/resources/icons/apply.png b/Annotation/resources/icons/apply.png
new file mode 100644 (file)
index 0000000..d7b5c2b
Binary files /dev/null and b/Annotation/resources/icons/apply.png differ
diff --git a/Annotation/resources/icons/auto.png b/Annotation/resources/icons/auto.png
new file mode 100644 (file)
index 0000000..a3e8c31
Binary files /dev/null and b/Annotation/resources/icons/auto.png differ
diff --git a/Annotation/resources/icons/background.png b/Annotation/resources/icons/background.png
new file mode 100644 (file)
index 0000000..0e633a3
Binary files /dev/null and b/Annotation/resources/icons/background.png differ
diff --git a/Annotation/resources/icons/brush.png b/Annotation/resources/icons/brush.png
new file mode 100644 (file)
index 0000000..4bb955f
Binary files /dev/null and b/Annotation/resources/icons/brush.png differ
diff --git a/Annotation/resources/icons/clear.png b/Annotation/resources/icons/clear.png
new file mode 100644 (file)
index 0000000..1556dfe
Binary files /dev/null and b/Annotation/resources/icons/clear.png differ
diff --git a/Annotation/resources/icons/close.png b/Annotation/resources/icons/close.png
new file mode 100644 (file)
index 0000000..78b931f
Binary files /dev/null and b/Annotation/resources/icons/close.png differ
diff --git a/Annotation/resources/icons/copy.png b/Annotation/resources/icons/copy.png
new file mode 100644 (file)
index 0000000..585579a
Binary files /dev/null and b/Annotation/resources/icons/copy.png differ
diff --git a/Annotation/resources/icons/dialog-error.png b/Annotation/resources/icons/dialog-error.png
new file mode 100644 (file)
index 0000000..c2d0bb7
Binary files /dev/null and b/Annotation/resources/icons/dialog-error.png differ
diff --git a/Annotation/resources/icons/dialog-information.png b/Annotation/resources/icons/dialog-information.png
new file mode 100644 (file)
index 0000000..23824bb
Binary files /dev/null and b/Annotation/resources/icons/dialog-information.png differ
diff --git a/Annotation/resources/icons/dialog-warning.png b/Annotation/resources/icons/dialog-warning.png
new file mode 100644 (file)
index 0000000..06148e8
Binary files /dev/null and b/Annotation/resources/icons/dialog-warning.png differ
diff --git a/Annotation/resources/icons/exit.png b/Annotation/resources/icons/exit.png
new file mode 100644 (file)
index 0000000..22a65a4
Binary files /dev/null and b/Annotation/resources/icons/exit.png differ
diff --git a/Annotation/resources/icons/experiment.png b/Annotation/resources/icons/experiment.png
new file mode 100644 (file)
index 0000000..cb16a60
Binary files /dev/null and b/Annotation/resources/icons/experiment.png differ
diff --git a/Annotation/resources/icons/export.png b/Annotation/resources/icons/export.png
new file mode 100644 (file)
index 0000000..f64425b
Binary files /dev/null and b/Annotation/resources/icons/export.png differ
diff --git a/Annotation/resources/icons/foreground.png b/Annotation/resources/icons/foreground.png
new file mode 100644 (file)
index 0000000..4161f1d
Binary files /dev/null and b/Annotation/resources/icons/foreground.png differ
diff --git a/Annotation/resources/icons/help.png b/Annotation/resources/icons/help.png
new file mode 100644 (file)
index 0000000..8542495
Binary files /dev/null and b/Annotation/resources/icons/help.png differ
diff --git a/Annotation/resources/icons/html.png b/Annotation/resources/icons/html.png
new file mode 100644 (file)
index 0000000..d95fcc0
Binary files /dev/null and b/Annotation/resources/icons/html.png differ
diff --git a/Annotation/resources/icons/icon-16.png b/Annotation/resources/icons/icon-16.png
new file mode 100644 (file)
index 0000000..b9e1264
Binary files /dev/null and b/Annotation/resources/icons/icon-16.png differ
diff --git a/Annotation/resources/icons/icon-24.png b/Annotation/resources/icons/icon-24.png
new file mode 100644 (file)
index 0000000..7b93ba1
Binary files /dev/null and b/Annotation/resources/icons/icon-24.png differ
diff --git a/Annotation/resources/icons/icon-32.png b/Annotation/resources/icons/icon-32.png
new file mode 100644 (file)
index 0000000..4bc8f32
Binary files /dev/null and b/Annotation/resources/icons/icon-32.png differ
diff --git a/Annotation/resources/icons/icon-48.png b/Annotation/resources/icons/icon-48.png
new file mode 100644 (file)
index 0000000..c3fca3e
Binary files /dev/null and b/Annotation/resources/icons/icon-48.png differ
diff --git a/Annotation/resources/icons/image.png b/Annotation/resources/icons/image.png
new file mode 100644 (file)
index 0000000..247ccad
Binary files /dev/null and b/Annotation/resources/icons/image.png differ
diff --git a/Annotation/resources/icons/next.png b/Annotation/resources/icons/next.png
new file mode 100644 (file)
index 0000000..0011e67
Binary files /dev/null and b/Annotation/resources/icons/next.png differ
diff --git a/Annotation/resources/icons/open-recent.png b/Annotation/resources/icons/open-recent.png
new file mode 100644 (file)
index 0000000..07cca3f
Binary files /dev/null and b/Annotation/resources/icons/open-recent.png differ
diff --git a/Annotation/resources/icons/open.png b/Annotation/resources/icons/open.png
new file mode 100644 (file)
index 0000000..c3bcfcd
Binary files /dev/null and b/Annotation/resources/icons/open.png differ
diff --git a/Annotation/resources/icons/preferences.png b/Annotation/resources/icons/preferences.png
new file mode 100644 (file)
index 0000000..e460eab
Binary files /dev/null and b/Annotation/resources/icons/preferences.png differ
diff --git a/Annotation/resources/icons/previous.png b/Annotation/resources/icons/previous.png
new file mode 100644 (file)
index 0000000..d3bc514
Binary files /dev/null and b/Annotation/resources/icons/previous.png differ
diff --git a/Annotation/resources/icons/print.png b/Annotation/resources/icons/print.png
new file mode 100644 (file)
index 0000000..2f1a0ff
Binary files /dev/null and b/Annotation/resources/icons/print.png differ
diff --git a/Annotation/resources/icons/redo.png b/Annotation/resources/icons/redo.png
new file mode 100644 (file)
index 0000000..57de992
Binary files /dev/null and b/Annotation/resources/icons/redo.png differ
diff --git a/Annotation/resources/icons/refresh.png b/Annotation/resources/icons/refresh.png
new file mode 100644 (file)
index 0000000..e46da27
Binary files /dev/null and b/Annotation/resources/icons/refresh.png differ
diff --git a/Annotation/resources/icons/reset.png b/Annotation/resources/icons/reset.png
new file mode 100644 (file)
index 0000000..1556dfe
Binary files /dev/null and b/Annotation/resources/icons/reset.png differ
diff --git a/Annotation/resources/icons/run.png b/Annotation/resources/icons/run.png
new file mode 100644 (file)
index 0000000..9010e7a
Binary files /dev/null and b/Annotation/resources/icons/run.png differ
diff --git a/Annotation/resources/icons/save-as.png b/Annotation/resources/icons/save-as.png
new file mode 100644 (file)
index 0000000..a838052
Binary files /dev/null and b/Annotation/resources/icons/save-as.png differ
diff --git a/Annotation/resources/icons/save.png b/Annotation/resources/icons/save.png
new file mode 100644 (file)
index 0000000..7da1d7c
Binary files /dev/null and b/Annotation/resources/icons/save.png differ
diff --git a/Annotation/resources/icons/undo.png b/Annotation/resources/icons/undo.png
new file mode 100644 (file)
index 0000000..48db6f2
Binary files /dev/null and b/Annotation/resources/icons/undo.png differ
diff --git a/Annotation/resources/icons/view.png b/Annotation/resources/icons/view.png
new file mode 100644 (file)
index 0000000..68da502
Binary files /dev/null and b/Annotation/resources/icons/view.png differ
diff --git a/Annotation/resources/icons/zoom-best-fit.png b/Annotation/resources/icons/zoom-best-fit.png
new file mode 100644 (file)
index 0000000..eb28409
Binary files /dev/null and b/Annotation/resources/icons/zoom-best-fit.png differ
diff --git a/Annotation/resources/icons/zoom-in.png b/Annotation/resources/icons/zoom-in.png
new file mode 100644 (file)
index 0000000..31ac736
Binary files /dev/null and b/Annotation/resources/icons/zoom-in.png differ
diff --git a/Annotation/resources/icons/zoom-original.png b/Annotation/resources/icons/zoom-original.png
new file mode 100644 (file)
index 0000000..8e35414
Binary files /dev/null and b/Annotation/resources/icons/zoom-original.png differ
diff --git a/Annotation/resources/icons/zoom-out.png b/Annotation/resources/icons/zoom-out.png
new file mode 100644 (file)
index 0000000..df5be3c
Binary files /dev/null and b/Annotation/resources/icons/zoom-out.png differ
diff --git a/Annotation/resources/plaf/debian/changelog b/Annotation/resources/plaf/debian/changelog
new file mode 100644 (file)
index 0000000..7036b2c
--- /dev/null
@@ -0,0 +1,169 @@
+ist (1.3.4-1) stable; urgency=low
+
+  * Support for Mac OS X leopard (64 bit JVM)
+  
+  * Fixed bug in transparent PNG export on Windows platforms
+
+ -- Kevin McGuinness <kevin.mcguinness@eeng.dcu.ie>  Thur, 27 Mar 2010 19:10:00 +0000
+
+ist (1.3.3-1) stable; urgency=low
+
+  * Updated API documentation
+
+  * Larger dialog for segmenter options
+
+  * Linux plugin builds now use GCC-4.1 for better compatibility
+
+ -- Kevin McGuinness <kevin.mcguinness@eeng.dcu.ie>  Wed, 7 Oct 2009 19:00:00 +0000
+
+ist (1.3.2-1) stable; urgency=low
+
+  * Moved more components to the API layer. This includes painters and the image
+    control. This allows other apps to share core components.
+    
+  * Added export transparent PNG option
+
+ -- Kevin McGuinness <kevin.mcguinness@eeng.dcu.ie>  Wed, 7 Oct 2009 18:00:00 +0000
+
+ist (1.3.1-1) stable; urgency=low
+
+  * Updated export HTML feature to export XHTML
+
+ -- Kevin McGuinness <kevin.mcguinness@eeng.dcu.ie>  Wed, 2 Sep 2009 18:00:00 +0000
+
+ist (1.3.0-1) stable; urgency=low
+
+  * Major restructuring of application to ease plugin development
+  
+  * New version of SWT
+  
+ -- Kevin McGuinness <kevin.mcguinness@eeng.dcu.ie>  Mon, 24 Aug 2009 18:00:00 +0000
+
+ist (1.2.5-1) stable; urgency=low
+
+  * Added code for automated evaluation
+  
+  * Update man page and run templates
+
+ -- Kevin McGuinness <kevin.mcguinness@eeng.dcu.ie>  Mon, 9 Mar 2009 16:21:00 +0000
+
+ist (1.2.4-1) stable; urgency=medium
+
+  * Fixed erratic behavior of SIOX segmenter
+  
+  * Added a lot of code for automated evaluation
+  
+  * Added option to force segmenters to retain all markup pixels in mask.
+  
+ -- Kevin McGuinness <kevin.mcguinness@eeng.dcu.ie>  Fri, 23 Jan 2009 18:00:00 +0000
+ist (1.2.3-1) stable; urgency=medium
+
+  * Fixed redo bug (redo was calling undo)
+  
+  * Segmentation context does not create an Image unless asked to now. This
+    prevents it initializing the swt Display object unless it needs to, allowing
+    console applications that use the core segmentation stuff to be created
+    without initializing the Display.
+  
+ -- Kevin McGuinness <kevin.mcguinness@eeng.dcu.ie>  Thu, 8 Jan 2009 15:00:00 +0000
+
+ist (1.2.2-1) stable; urgency=low
+
+  * Fixed application name in menu bar on OS X
+  
+ -- Kevin McGuinness <kevin.mcguinness@eeng.dcu.ie>  Tue, 6 Jan 2009 15:00:00 +0000
+
+ist (1.2.1-1) stable; urgency=low
+
+  * Use command key instead of ctrl key for shortcuts on Mac OSX
+  
+  * Zip file for app bundle on OS X: it's better supported than tar.gz
+  
+  * Modified about box to display SWT version
+  
+  * Added standard Command+, binding for preferences on Mac
+  
+  * Use small icons in menus on all platforms
+  
+  * Removed icons in preference dialog buttons on Mac OS
+  
+  * Improved and included several new icons
+  
+  * Fixed visual bug on linux: horizontal separators didn't look right in
+    the export dialog.
+  
+ -- Kevin McGuinness <kevin.mcguinness@eeng.dcu.ie>  Wed, 17 Dec 2008 17:00:00 +0000
+
+ist (1.2.0-1) stable; urgency=low
+  
+  * New feature: export to HTML image maps integrated. Supports exporting 
+    polygons and rectangles for now. Can export several rollover effects using 
+    the javascript image swapping technique.
+    
+  * Fixed bug on Mac OS X: application did not always exit properly
+  
+  * Open browser window to show the HTML page when export completes
+  
+  * Option to turn on or off the open browser window behavior
+  
+  * Best practices: use var for global image preloads.
+    
+ -- Kevin McGuinness <kevin.mcguinness@eeng.dcu.ie>  Tue, 16 Dec 2008 21:37:00 +0000
+
+ist (1.1.0-1) stable; urgency=low
+  
+  * Several new features are planned for introduction, so the version number
+    has been incremented to 1.1
+  
+  * Changed context file format. This is now stored as a zip archive including 
+    the image, mask and annotations, so that it is more "self-contained". The
+    new file format is NOT compatible with the old one.
+    
+ -- Kevin McGuinness <kevin.mcguinness@eeng.dcu.ie>  Tue, 29 Feb 2008 12:25:00 +0000
+
+ist (1.0.6-1) stable; urgency=low
+
+  * Added startup check for gdiplus.dll for platforms where it's needed but not 
+    installed by default. Program will now show a useful message and exit gracefully
+    instead of spewing stack traces on the console and behaving oddly.
+    
+  * Fixed bug that caused the auto-apply toggle button to be always disabled
+    after first image load.
+
+ -- Kevin McGuinness <kevin.mcguinness@eeng.dcu.ie>  Tue, 28 Feb 2008 10:36:00 +0000
+
+ist (1.0.5-1) stable; urgency=medium
+
+  * Fixed bug that caused the brush control (and some other toolbar buttons) to be
+    disabled after an experiment was cancelled.
+
+ -- Kevin McGuinness <kevin.mcguinness@eeng.dcu.ie>  Tue, 12 Feb 2008 13:25:00 +0000
+ist (1.0.4-1) stable; urgency=low
+
+  * Updated the integrated help file (help.html)
+
+ -- Kevin McGuinness <kevin.mcguinness@eeng.dcu.ie>  Tue, 28 Jan 2008 16:40:00 +0000
+
+ist (1.0.3-1) stable; urgency=low
+
+  * MacOSX PowerPC now supported
+
+  * Mostly non-functional changes on Linux, refactoring and the like
+
+ -- Kevin McGuinness <kevin.mcguinness@eeng.dcu.ie>  Tue, 25 Jan 2008 16:08:00 +0000
+
+ist (1.0.2-1) stable; urgency=low
+
+  * Application icon added
+
+ -- Kevin McGuinness <kevin.mcguinness@eeng.dcu.ie>  Tue, 16 Jan 2008 19:43:00 +0000
+
+ist (1.0.1-1) stable; urgency=low
+
+  * Created debian package
+  
+  * Support added for 64 bit linux
+
+ -- Kevin McGuinness <kevin.mcguinness@eeng.dcu.ie>  Tue, 15 Jan 2008 19:43:00 +0000
diff --git a/Annotation/resources/plaf/debian/copyright b/Annotation/resources/plaf/debian/copyright
new file mode 100644 (file)
index 0000000..32da294
--- /dev/null
@@ -0,0 +1,10 @@
+ist
+
+Copyright: Kevin McGuinness <kevin.mcguinness@eeng.dcu.ie>
+           Center for Digital Video Processing
+           Dublin City University
+
+2008-01-14
+
+The home page of ist is at: 
+https://www.kspace.cdvp.dcu.ie/public/interactive-segmentation
diff --git a/Annotation/resources/plaf/debian/desktop b/Annotation/resources/plaf/debian/desktop
new file mode 100644 (file)
index 0000000..718ced1
--- /dev/null
@@ -0,0 +1,10 @@
+# freedesktop.org desktop entry
+[Desktop Entry]
+Version=1.0
+Type=Application
+Name=Interactive Segmentation Tool
+Comment=Interactively extract objects from images using various algorithms
+Icon=ist
+Exec=ist
+Terminal=false
+Categories=GTK;Graphics
diff --git a/Annotation/resources/plaf/debian/ist b/Annotation/resources/plaf/debian/ist
new file mode 100644 (file)
index 0000000..d1e385d
--- /dev/null
@@ -0,0 +1,36 @@
+#!/bin/sh
+
+# Setup
+data=@data@
+main=@main@
+jars=@jars@
+
+# Change directory
+cd "${data}"
+
+# This is needed for the browser widget on linux
+if [ -z "${MOZILLA_FIVE_HOME}" ]; then
+       # Check if common locations exist
+       if [ -d "/usr/lib/firefox" ]; then
+               export MOZILLA_FIVE_HOME=/usr/lib/firefox
+       elif [ -d "/usr/lib/mozilla-firefox" ]; then
+               export MOZILLA_FIVE_HOME=/usr/lib/mozilla-firefox
+       elif [ -d "/usr/lib/mozilla" ]; then
+               export MOZILLA_FIVE_HOME=/usr/lib/mozilla
+       fi
+fi
+
+# Set library path
+if [ -n "${MOZILLA_FIVE_HOME}" ]; then
+       export LD_LIBRARY_PATH=${MOZILLA_FIVE_HOME}:${LD_LIBRARY_PATH}
+fi
+
+# Launch
+if [ -n "${JAVA_HOME}" ]; then
+       ${JAVA_HOME}/bin/java -classpath "${jars}" ${main} $*
+else
+       java -classpath "${jars}" ${main} $*
+fi
+
+cd "$OLDPWD"
+
diff --git a/Annotation/resources/plaf/debian/ist.1 b/Annotation/resources/plaf/debian/ist.1
new file mode 100644 (file)
index 0000000..29faaf6
--- /dev/null
@@ -0,0 +1,29 @@
+.TH "ist" "1" "1.3.3" "Kevin McGuinness" "Graphics"
+.SH "NAME"
+.LP 
+ist \- Interactive Segmentation Tool
+.SH "SYNTAX"
+.LP 
+ist [options]
+
+.SH "DESCRIPTION"
+.LP 
+Launches the interactive segmentation tool graphical user interface
+
+.SH "ENVIRONMENT VARIABLES"
+.LP 
+.TP 
+\fBMOZILLA_FIVE_HOME\fP
+Specifies the location of the mozilla 5 browser 
+(firefox etc.). This is usually something like 
+/usr/lib/firefox
+
+.SH "EXAMPLES"
+.LP 
+To run this program the standard way type:
+.LP 
+$ ist
+
+.SH "AUTHORS"
+.LP 
+Kevin McGuinness <kevin.mcguinness@eeng.dcu.ie>
diff --git a/Annotation/resources/plaf/debian/postinst b/Annotation/resources/plaf/debian/postinst
new file mode 100644 (file)
index 0000000..fb29bea
--- /dev/null
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+sudo update-desktop-database
+sudo gtk-update-icon-cache /usr/share/icons/hicolor
diff --git a/Annotation/resources/plaf/debian/postrm b/Annotation/resources/plaf/debian/postrm
new file mode 100644 (file)
index 0000000..fb29bea
--- /dev/null
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+sudo update-desktop-database
+sudo gtk-update-icon-cache /usr/share/icons/hicolor
diff --git a/Annotation/resources/plaf/linux/ist b/Annotation/resources/plaf/linux/ist
new file mode 100644 (file)
index 0000000..1f45a3a
--- /dev/null
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+jars=istapp.jar:istapi.jar:swt.jar:jface.jar
+main=ie.dcu.apps.ist.Main
+
+# Change directory
+cd "`dirname "$0"`"
+
+# This is needed for the SWT browser widget on linux
+if [ -z "${MOZILLA_FIVE_HOME}" ]; then
+
+       # Check if common locations exist
+       if [ -d "/usr/lib/firefox" ]; then
+               export MOZILLA_FIVE_HOME=/usr/lib/firefox
+       elif [ -d "/usr/lib/mozilla-firefox" ]; then
+               export MOZILLA_FIVE_HOME=/usr/lib/mozilla-firefox
+       elif [ -d "/usr/lib/mozilla" ]; then
+               export MOZILLA_FIVE_HOME=/usr/lib/mozilla
+       fi
+       
+fi
+
+# Set library path
+if [ -n "${MOZILLA_FIVE_HOME}" ]; then
+       export LD_LIBRARY_PATH=${MOZILLA_FIVE_HOME}:${LD_LIBRARY_PATH}
+fi
+
+if [ -n "${JAVA_HOME}" ]; then
+       ${JAVA_HOME}/bin/java -classpath "${jars}"  ${main} $*
+else
+       java -classpath "${jars}" ${main} $*
+fi
+
+cd "$OLDPWD"
diff --git a/Annotation/resources/plaf/mac/Info.plist b/Annotation/resources/plaf/mac/Info.plist
new file mode 100644 (file)
index 0000000..0fbcac6
--- /dev/null
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
+                       "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+  <dict>
+    <key>CFBundleName</key>
+    <string>@name@</string>
+    <key>CFBundleShortVersionString</key>
+    <string>@version@</string>
+    <key>CFBundleGetInfoString</key>
+    <string>@synopsis@ (v@version@)</string>
+    <key>CFBundleAllowMixedLocalizations</key>
+    <string>false</string>
+    <key>CFBundleInfoDictionaryVersion</key>
+    <string>6.0</string>
+    <key>CFBundleExecutable</key>
+    <string>@exename@</string>
+    <key>CFBundleDevelopmentRegion</key>
+    <string>English</string>
+    <key>CFBundlePackageType</key>
+    <string>APPL</string>
+    <key>CFBundleSignature</key>
+    <string>????</string>
+    <key>CFBundleIconFile</key>
+    <string>@icons@</string>
+  </dict>
+</plist>
diff --git a/Annotation/resources/plaf/mac/PkgInfo b/Annotation/resources/plaf/mac/PkgInfo
new file mode 100644 (file)
index 0000000..6f749b0
--- /dev/null
@@ -0,0 +1 @@
+APPL????
diff --git a/Annotation/resources/plaf/mac/icon.icns b/Annotation/resources/plaf/mac/icon.icns
new file mode 100644 (file)
index 0000000..ae867d3
Binary files /dev/null and b/Annotation/resources/plaf/mac/icon.icns differ
diff --git a/Annotation/resources/plaf/mac/ist b/Annotation/resources/plaf/mac/ist
new file mode 100644 (file)
index 0000000..07663d1
--- /dev/null
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+# What kinda mac are we on
+CPU=`uname -p`
+
+# Absolute path to where the app was launched from
+APP_PACKAGE="`dirname "$0"`/../.."
+APP_PACKAGE="`cd "${APP_PACKAGE}"; pwd`"
+
+# Locations of resources, jars, and libs
+LIB_DIR="Libraries/${CPU}"
+
+# Move to the resource directory
+cd "${APP_PACKAGE}/Contents/Resources"
+
+# Establish whether we should use the 32 bit or 64 bit cocoa library
+SWT_LIBNAME=swt-cocoa-32.jar
+java -version 2>&1 | grep "64-Bit" > /dev/null
+if [ "$?" -eq "0" ]; then
+       SWT_LIBNAME=swt-cocoa-64.jar
+fi
+
+echo "SWT Library: ${SWT_LIBNAME}"
+
+# Launch app
+java \
+  -XstartOnFirstThread \
+  -classpath "Java/istapp.jar:Java/istapi.jar:Java/jface.jar:Java/${SWT_LIBNAME}" \
+  -Dorg.eclipse.swt.internal.carbon.noFocusRing \
+  -Dorg.eclipse.swt.internal.carbon.smallFonts \
+  @appmain@ $*
+
+# Go back to the old working directory
+cd "${OLDPWD}"
diff --git a/Annotation/resources/plaf/windows/application.ico b/Annotation/resources/plaf/windows/application.ico
new file mode 100644 (file)
index 0000000..ae1ac33
Binary files /dev/null and b/Annotation/resources/plaf/windows/application.ico differ
diff --git a/Annotation/resources/plaf/windows/install.xml b/Annotation/resources/plaf/windows/install.xml
new file mode 100644 (file)
index 0000000..23cb85e
--- /dev/null
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="iso-8859-1" standalone="yes" ?>
+
+<!-- 
+    IzPack install file for the Interactive Segmentation Tool
+-->
+
+<installation version="1.0">
+
+    <!-- The info section. -->
+    <info>
+        <appname>@name@</appname>
+        <appversion>@version@</appversion>
+        <authors>
+            <author name="@author@" email="@email@"/>
+        </authors>
+        <url>@website@</url>
+        <javaversion>1.5</javaversion>
+    </info>
+
+    <!-- The gui preferences indication. -->
+    <guiprefs width="640" height="480" resizable="no"/>
+
+    <!-- The locale section. -->
+    <locale>
+        <langpack iso3="eng"/>
+    </locale>
+
+    <!-- The resources section. -->
+    <resources>
+        <res src="resources/plaf/windows/shortcuts.xml" id="shortcutSpec.xml"/>
+    </resources>
+
+    <!-- Shell-link for windows. -->
+    <native type="izpack" name="ShellLink.dll" />
+
+    <!-- The panels section. -->
+    <panels>
+        <panel classname="HelloPanel"/>
+        <panel classname="TargetPanel"/> 
+        <panel classname="PacksPanel"/>
+        <panel classname="InstallPanel"/>
+        <panel classname="ShortcutPanel"/>
+        <panel classname="FinishPanel"/>
+    </panels>
+
+    <!-- The packs section. -->
+    <packs>
+        <pack name="Base" required="yes">
+            <description> Base installation files </description>
+            <fileset dir="build/packages/windows" targetdir="${INSTALL_PATH}" >
+                <include name="**/*" />
+            </fileset>
+        </pack>
+    </packs>
+    
+</installation>
diff --git a/Annotation/resources/plaf/windows/installer.ico b/Annotation/resources/plaf/windows/installer.ico
new file mode 100644 (file)
index 0000000..66d530f
Binary files /dev/null and b/Annotation/resources/plaf/windows/installer.ico differ
diff --git a/Annotation/resources/plaf/windows/installer.jsmooth b/Annotation/resources/plaf/windows/installer.jsmooth
new file mode 100644 (file)
index 0000000..823d035
--- /dev/null
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<jsmoothproject>
+    <JVMSearchPath>registry</JVMSearchPath>
+    <JVMSearchPath>javahome</JVMSearchPath>
+    <JVMSearchPath>jrepath</JVMSearchPath>
+    <JVMSearchPath>jdkpath</JVMSearchPath>
+    <JVMSearchPath>exepath</JVMSearchPath>
+    <JVMSearchPath>jview</JVMSearchPath>
+    <jarLocation>@input@</jarLocation>
+    <iconLocation>@icon@</iconLocation>
+    <currentDirectory>${EXECUTABLEPATH}</currentDirectory>
+    <embeddedJar>true</embeddedJar>
+    <executableName>@output@</executableName>
+    <initialMemoryHeap>-1</initialMemoryHeap>
+    <mainClassName>com.izforge.izpack.installer.Installer</mainClassName>
+    <maximumMemoryHeap>-1</maximumMemoryHeap>
+    <maximumVersion></maximumVersion>
+    <minimumVersion>1.5</minimumVersion>
+    <skeletonName>Windowed Wrapper</skeletonName>
+    <skeletonProperties>
+        <key>Message</key>
+        <value>Java has not been found on your computer.
+        Do you want to download it?</value>
+    </skeletonProperties>
+    <skeletonProperties>
+        <key>Debug</key>
+        <value>0</value>
+    </skeletonProperties>
+</jsmoothproject>
diff --git a/Annotation/resources/plaf/windows/ist.jsmooth b/Annotation/resources/plaf/windows/ist.jsmooth
new file mode 100644 (file)
index 0000000..52388f9
--- /dev/null
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<jsmoothproject>
+    <JVMSearchPath>registry</JVMSearchPath>
+    <JVMSearchPath>javahome</JVMSearchPath>
+    <JVMSearchPath>jrepath</JVMSearchPath>
+    <JVMSearchPath>jdkpath</JVMSearchPath>
+    <JVMSearchPath>exepath</JVMSearchPath>
+    <JVMSearchPath>jview</JVMSearchPath>
+    <classPath>istapp.jar</classPath>
+    <classPath>istapi.jar</classPath>
+    <classPath>swt-win.jar</classPath>
+    <classPath>jface.jar</classPath>
+    <currentDirectory>${EXECUTABLEPATH}</currentDirectory>
+    <embeddedJar>false</embeddedJar>
+    <executableName>ist.exe</executableName>
+    <iconLocation>application.ico</iconLocation>
+    <initialMemoryHeap>-1</initialMemoryHeap>
+    <mainClassName>ie.dcu.apps.ist.Main</mainClassName>
+    <maximumMemoryHeap>-1</maximumMemoryHeap>
+    <minimumVersion>1.5.0</minimumVersion>
+    <skeletonName>Windowed Wrapper</skeletonName>
+    <skeletonProperties>
+        <key>Message</key>
+        <value>This program needs Java to run.
+        Please download it at http://www.java.com</value>
+    </skeletonProperties>
+    <skeletonProperties>
+        <key>Debug</key>
+        <value>0</value>
+    </skeletonProperties>
+</jsmoothproject>
diff --git a/Annotation/resources/plaf/windows/shortcuts.xml b/Annotation/resources/plaf/windows/shortcuts.xml
new file mode 100644 (file)
index 0000000..d34c867
--- /dev/null
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>\r
+<shortcuts>\r
+       <skipIfNotSupported/>\r
+       <programGroup defaultName="IST" location="applications"/>\r
+       \r
+       <shortcut\r
+               name="Interactive Segmentation Tool"\r
+               target="$INSTALL_PATH\ist.exe"\r
+               workingDirectory="$INSTALL_PATH"\r
+               description="Launch the Interactive Segmentation Tool"\r
+               initialState="normal"\r
+               programGroup="yes"\r
+               desktop="yes"\r
+               applications="no"\r
+               startMenu="no"\r
+               startup="no"\r
+       >\r
+               <createForPack name="Base"/>\r
+       </shortcut>\r
+\r
+       <shortcut\r
+               name="Uninstall"\r
+               target="${JAVA_HOME}\bin\java.exe"\r
+               commandLine="-jar &quot;$INSTALL_PATH/Uninstaller/uninstaller.jar&quot;"\r
+               description="Uninstall Interactive Segmentation Tool"\r
+               initialState="noShow"\r
+               programGroup="yes"\r
+               desktop="no"\r
+               applications="no"\r
+               startMenu="no"\r
+               startup="no"\r
+       >\r
+               <createForPack name="Base"/>\r
+       </shortcut>\r
+\r
+</shortcuts>\r
diff --git a/Annotation/resources/plaf/windows/skeletons/windowed-wrapper/description.skel b/Annotation/resources/plaf/windows/skeletons/windowed-wrapper/description.skel
new file mode 100644 (file)
index 0000000..52acb08
--- /dev/null
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<jsmoothskeleton>
+<debug>false</debug>
+<description>SKEL_SIMPLEWRAPPER_DESCRIPTION</description>
+<executableName>jwrap.exe</executableName>
+<resourceCategory>JAVA</resourceCategory>
+<resourceJarId>102</resourceJarId>
+<resourcePropsId>103</resourcePropsId>
+<shortName>Windowed Wrapper</shortName>
+<skeletonProperties>
+<description>SKEL_SIMPLEWRAPPER_PROPERTY_MESSAGE_DESCRIPTION</description>
+<idName>Message</idName>
+<label>SKEL_SIMPLEWRAPPER_PROPERTY_MESSAGE_LABEL</label>
+<type>textarea</type>
+<value>Java has not been found on your computer. Do you want to download it?</value>
+</skeletonProperties>
+<skeletonProperties>
+<description>SKEL_SIMPLEWRAPPER_PROPERTY_URL_DESCRIPTION</description>
+<idName>URL</idName>
+<label>SKEL_SIMPLEWRAPPER_PROPERTY_URL_LABEL</label>
+<type>string</type>
+<value>http://www.java.com</value>
+</skeletonProperties>
+<skeletonProperties>
+<description>SKEL_GENERIC_PROPERTY_SINGLEPROCESS_DESCRIPTION</description>
+<idName>SingleProcess</idName>
+<label>SKEL_GENERIC_PROPERTY_SINGLEPROCESS_LABEL</label>
+<type>boolean</type>
+<value>0</value>
+</skeletonProperties>
+<skeletonProperties>
+<description>SKEL_GENERIC_SINGLEINSTANCE_DESCRIPTION</description>
+<idName>SingleInstance</idName>
+<label>SKEL_GENERIC_SINGLEINSTANCE</label>
+<type>boolean</type>
+<value>0</value>
+</skeletonProperties>
+<skeletonProperties>
+<description>SKEL_GENERIC_JNISMOOTH_DESCRIPTION</description>
+<idName>JniSmooth</idName>
+<label>SKEL_GENERIC_JNISMOOTH</label>
+<type>boolean</type>
+<value>0</value>
+</skeletonProperties>
+<skeletonProperties>
+<description>SKEL_GENERIC_PROPERTY_DEBUG_DESCRIPTION</description>
+<idName>Debug</idName>
+<label>SKEL_GENERIC_PROPERTY_DEBUG_LABEL</label>
+<type>boolean</type>
+<value>0</value>
+</skeletonProperties>
+</jsmoothskeleton>
diff --git a/Annotation/resources/plaf/windows/skeletons/windowed-wrapper/jwrap.exe b/Annotation/resources/plaf/windows/skeletons/windowed-wrapper/jwrap.exe
new file mode 100755 (executable)
index 0000000..436402d
Binary files /dev/null and b/Annotation/resources/plaf/windows/skeletons/windowed-wrapper/jwrap.exe differ
diff --git a/Annotation/src/ie/dcu/apps/ist/AppPrefs.java b/Annotation/src/ie/dcu/apps/ist/AppPrefs.java
new file mode 100644 (file)
index 0000000..fabc554
--- /dev/null
@@ -0,0 +1,259 @@
+package ie.dcu.apps.ist;
+
+import ie.dcu.swt.SwtUtils;
+
+import java.util.*;
+import java.util.logging.Logger;
+import java.util.prefs.*;
+
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * Manages application preferences
+ * 
+ * @author Kevin McGuinness
+ */
+public class AppPrefs {
+       
+       public interface Keys {
+               public static final String ENABLE_FEEDBACK = "enable-feedback";
+               public static final String FOREGROUND_COLOR = "foreground-color";
+               public static final String BACKGROUND_COLOR = "background-color";
+               public static final String EXPERIMENT_EMBEDDED = "experiment-embedded";
+               public static final String CONFIRM_EXIT = "confirm-exit";
+       }
+       
+       public interface SupportedTypes {
+               public static final Class<Integer> INTEGER = Integer.class;
+               public static final Class<Double>  DOUBLE  = Double.class;
+               public static final Class<Float>   FLOAT   = Float.class;
+               public static final Class<Short>   SHORT   = Short.class;
+               public static final Class<Byte>    BYTE    = Byte.class;
+               public static final Class<Long>    LONG    = Long.class;
+               public static final Class<String>  STRING  = String.class;
+               public static final Class<Boolean> BOOLEAN = Boolean.class;
+               public static final Class<RGB>     RGB     = RGB.class;
+       }
+       
+       
+       private final Logger log;
+       private final Preferences prefs;
+       private final List<PreferenceChangeListener> listeners;
+
+       
+       public AppPrefs() {
+               this.log = Logger.getLogger(getClass().getName());
+               this.prefs = Preferences.userRoot().node(Application.APP_ID);
+               this.listeners = new LinkedList<PreferenceChangeListener>();
+               
+               addSwtThreadAdaptionListener();
+       }
+       
+       
+       private void addSwtThreadAdaptionListener() {
+               prefs.addPreferenceChangeListener(new PreferenceChangeListener() {
+                       public void preferenceChange(PreferenceChangeEvent evt) {
+                               firePreferenceChangedSynced(evt);
+                       }
+               });
+       }
+
+
+       private void firePreferenceChangedSynced(final PreferenceChangeEvent evt) {
+                       
+               // Delegate to event SWT event dispatching thread
+               Display.getDefault().syncExec(new Runnable() {
+                       public void run() {
+                               firePreferenceChanged(evt);     
+                       }
+               });
+       
+       }
+
+
+       private void firePreferenceChanged(PreferenceChangeEvent evt) {
+               for (PreferenceChangeListener listener : listeners) {
+                       listener.preferenceChange(evt);
+               }
+       }
+
+
+       public void sync() {
+               try {
+                       prefs.sync();
+               } catch (BackingStoreException e) {
+                       log.warning("Error syncing preferences: " + e.getMessage());
+               }
+       }
+       
+       
+       public void flush() {
+               try {
+                       prefs.flush();
+               } catch (BackingStoreException e) {
+                       log.warning("Error writing preferences: " + e.getMessage());
+               }
+       }
+       
+
+       public void clear() {
+               try {
+                       prefs.clear();
+               } catch (BackingStoreException e) {
+                       log.warning("Error clearing preferences: " + e.getMessage());
+               }
+       }
+
+
+       public String[] keys() {
+               try {
+                       return prefs.keys();
+               } catch (BackingStoreException e) {
+                       log.warning("Error retrieving preference keys: " + e.getMessage());
+               }
+               return new String[0];
+       }
+
+
+       public void remove(String key) {
+               prefs.remove(key);
+       }
+
+
+       public <T> T get(Class<T> clazz, String key, T def) {
+               String value =  (def != null) ? 
+                               get(key, def.toString()) : get(key, null);
+               
+               return decode(clazz, value, def);
+       }
+       
+
+       public <T> void put(Class<T> clazz, String key, T value) {
+               prefs.put(key, encode(clazz, value));
+       }
+       
+       
+       public void put(String key, String value) {
+               prefs.put(key, value);
+       }
+       
+       
+       public String get(String key, String def) {
+               return prefs.get(key, def);
+       }
+       
+       
+       public void addPreferenceChangeListener(PreferenceChangeListener pcl) {
+               listeners.add(pcl);
+       }
+
+
+       public void removePreferenceChangeListener(PreferenceChangeListener pcl) {
+               listeners.remove(pcl);
+       }
+
+
+       public <T> String encode(Class<T> clazz, T value) {
+               if (clazz.equals(RGB.class)) {
+                       return encodeRGB((RGB) value);
+               } else if (value != null) {
+                       return String.valueOf(value);
+               } else {
+                       return null;
+               }
+       }
+       
+       
+       public <T> T decode(Class<T> clazz, String str, T def) {
+               if (str == null) {
+                       return def;
+               }       else if (isNumeric(clazz)) {
+                       return clazz.cast(decodeNumeric(clazz, str, def));
+               } else if (isString(clazz)) {
+                       return clazz.cast(str);
+               } else if (isBoolean(clazz)) {
+                       return clazz.cast(decodeBoolean(str, (Boolean) def));
+               } else if (clazz.equals(RGB.class)) {
+                       return clazz.cast(decodeRGB(str, (RGB) def));
+               } else {
+                       log.warning("Unable to decode class: " + clazz.getName());
+               }
+               
+               return def;
+       }
+       
+       
+       private boolean isString(Class<?> clazz) {
+               return clazz.equals(String.class);
+       }
+       
+       
+       private boolean isBoolean(Class<?> clazz) {
+               return clazz.equals(Boolean.class);
+       }
+       
+       
+       
+       private boolean isNumeric(Class<?> clazz) {
+               return 
+                       clazz.equals(Integer.class) ||
+                       clazz.equals(Double.class) ||
+                       clazz.equals(Float.class) ||
+                       clazz.equals(Short.class) ||
+                       clazz.equals(Byte.class) ||
+                       clazz.equals(Long.class);      
+       }
+       
+       
+       private RGB decodeRGB(String str, RGB def) {
+               if (str.startsWith("#")) {
+                       try {
+                               int hex = Integer.parseInt(str.substring(1), 16);
+                               return SwtUtils.int2rgb(hex);
+                       } catch (NumberFormatException e) {
+                               log.warning("Not a valid color: " + str);
+                       }
+               }
+               return def;
+       }
+       
+       
+       private String encodeRGB(RGB rgb) {
+               return String.format("#%06x", SwtUtils.rgb2int(rgb));
+       }
+       
+       
+       private boolean decodeBoolean(String str, boolean def) {
+               return str.equalsIgnoreCase("true") ||
+                       (str.equalsIgnoreCase("false") ? false : def);
+       }
+       
+       
+       private <T> T decodeNumeric(Class<T> clazz, String s, T def) {
+               try {
+                       if (clazz.equals(Integer.class)) {
+                               return clazz.cast(Integer.parseInt(s));
+                               
+                       } else if (clazz.equals(Double.class)) {
+                               return clazz.cast(Double.parseDouble(s));
+                       
+                       } else if (clazz.equals(Float.class)) {
+                               return clazz.cast(Float.parseFloat(s));
+                       
+                       } else if (clazz.equals(Short.class)) {
+                               return clazz.cast(Short.parseShort(s));
+                       
+                       } else if (clazz.equals(Byte.class)) {
+                               return clazz.cast(Byte.parseByte(s));
+                       
+                       } else if (clazz.equals(Long.class)) {
+                               return clazz.cast(Long.parseLong(s));
+                       
+                       }  
+               } catch (NumberFormatException ex) {
+                       log.warning("Invalid numeric value in preferences: " + s);
+               }
+               return def;
+       }
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/AppPrefsManager.java b/Annotation/src/ie/dcu/apps/ist/AppPrefsManager.java
new file mode 100644 (file)
index 0000000..e41ea3b
--- /dev/null
@@ -0,0 +1,97 @@
+package ie.dcu.apps.ist;
+
+import static ie.dcu.segment.annotate.AnnotationType.*;
+import static ie.dcu.apps.ist.AppPrefs.Keys.*;
+import static ie.dcu.apps.ist.AppPrefs.SupportedTypes.*;
+import ie.dcu.segment.annotate.*;
+import ie.dcu.apps.ist.AppPrefs.*;
+
+import java.util.prefs.*;
+
+import org.eclipse.jface.resource.*;
+import org.eclipse.swt.graphics.*;
+
+/**
+ * Manages updating various components when preferences change.
+ * 
+ * @author Kevin McGuinness
+ */
+class AppPrefsManager implements PreferenceChangeListener {
+       
+       private final AppWindow window;
+       private final ColorRegistry colorRegistry;
+       private final AppPrefs prefs;
+       
+
+       public AppPrefsManager(AppWindow window) {
+               this.window = window;
+               this.colorRegistry = JFaceResources.getColorRegistry();
+               this.prefs = loadPreferences();
+       }
+       
+       
+       private AppPrefs loadPreferences() {
+               AppPrefs prefs = new AppPrefs();
+               prefs.addPreferenceChangeListener(this);
+               return prefs;
+       }
+       
+       
+       public AppPrefs getPrefs() {
+               return prefs;
+       }
+       
+       
+       public void update() {
+               updateFeedbackEnabled();
+               updateBackgroundColor();
+               updateForegroundColor();
+               updateExperimentEmbedded();
+       }
+       
+       
+       public void updateExperimentEmbedded() {
+               boolean on = prefs.get(BOOLEAN, Keys.EXPERIMENT_EMBEDDED, false);
+               window.setExperimentModeEmbedded(on);
+       }
+       
+       
+       public void updateFeedbackEnabled() {
+               boolean on = prefs.get(BOOLEAN, Keys.ENABLE_FEEDBACK, true);
+               window.setEnableFeedback(on);
+       }
+       
+       
+       public void updateForegroundColor() {
+               RGB color = prefs.get(RGB, Keys.FOREGROUND_COLOR, DEFAULT_FOREGROUND);
+               colorRegistry.put(AnnotationType.Foreground.key, color);
+               window.getView().repaint();
+       }
+       
+       
+       public void updateBackgroundColor() {
+               RGB color = prefs.get(RGB, Keys.BACKGROUND_COLOR, DEFAULT_BACKGROUND);
+               colorRegistry.put(AnnotationType.Background.key, color);
+               window.getView().repaint();
+       }
+       
+
+       public void preferenceChange(PreferenceChangeEvent evt) {
+               String pref = evt.getKey();
+               
+               if (pref.equals(ENABLE_FEEDBACK)) {
+                       updateFeedbackEnabled();
+               
+               } else if (pref.equals(FOREGROUND_COLOR)) {
+                       updateForegroundColor();
+               
+               } else if (pref.equals(BACKGROUND_COLOR)) {
+                       updateBackgroundColor();
+                       
+               } else if (pref.equals(EXPERIMENT_EMBEDDED)) {
+                       updateExperimentEmbedded();
+               }
+
+       }
+
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/AppRecentFiles.java b/Annotation/src/ie/dcu/apps/ist/AppRecentFiles.java
new file mode 100644 (file)
index 0000000..c2b7b31
--- /dev/null
@@ -0,0 +1,93 @@
+package ie.dcu.apps.ist;
+
+import ie.dcu.apps.ist.recent.*;
+
+import java.io.*;
+
+/**
+ * Manages applications recent files list.
+ * 
+ * @author Kevin McGuinness
+ */
+public class AppRecentFiles extends RecentFiles {
+       public static final String APP_SETTINGS_PATH = ".ist";
+       public static final String HISTORY_FILE_NAME = ".history";
+
+       private static AppRecentFiles history;
+       
+       
+       private AppRecentFiles(File store) {
+               super(store);
+       }
+       
+       
+       public static AppRecentFiles getInstance() {
+               if (history == null) {
+                       history = create();
+               }
+               return history;
+       }
+       
+       
+       private static AppRecentFiles create() {
+               AppRecentFiles history = null;
+               try {
+                       history = new AppRecentFiles(getHistoryFile());
+                       history.load();
+               } catch (IOException e) {
+                       getLogger().warning("Unable to create history file: " + e);
+               }
+               
+               return history;
+       }
+       
+       
+       @Override
+       public void load() {
+               try {
+                       super.load();
+               } catch (IOException e) {
+                       getLogger().warning("Error loading recent documents list: " + e);
+               }
+       }
+
+       @Override
+       public void store() {
+               try {
+                       super.store();
+               } catch (IOException e) {
+                       getLogger().warning("Error storing recent documents list: " + e);
+               }
+       }
+
+
+       private static File getHistoryFile() throws IOException {
+               File file = new File(getSettingsDirectory(), HISTORY_FILE_NAME);
+               if (file.exists()) {
+                       // Check we can write
+                       if (file.canWrite()) {
+                               return file;
+                       }
+               } else {
+                       return file;
+               }
+               
+               throw new IOException("History file is unwritable");
+       }
+
+
+       private static File getSettingsDirectory() throws IOException {
+               String home = System.getProperty("user.home");
+               File settings = new File(home, APP_SETTINGS_PATH);
+               
+               if (!settings.exists()) {
+                       if (settings.mkdirs()) {
+                               return settings;
+                       }
+               } else {
+                       return settings;
+               }
+               
+               throw new IOException("Unable to create application settings directory");
+       }
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/AppRecentMenu.java b/Annotation/src/ie/dcu/apps/ist/AppRecentMenu.java
new file mode 100644 (file)
index 0000000..84fe0cb
--- /dev/null
@@ -0,0 +1,113 @@
+/**
+ * 
+ */
+package ie.dcu.apps.ist;
+
+import ie.dcu.apps.ist.actions.ActionManager;
+import ie.dcu.apps.ist.actions.HoverMenuManager;
+import ie.dcu.apps.ist.actions.OpenAction;
+import ie.dcu.apps.ist.actions.OpenRecentAction;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Properties;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+
+/**
+ * Recent files menu.
+ * 
+ * @author Kevin McGuinness
+ */
+class AppRecentMenu extends HoverMenuManager {
+       private final AppRecentFiles history;
+       private final EmptyAction empty;
+       private final AppWindow window;
+       private IAction action;
+       
+       public AppRecentMenu(AppWindow window, IMenuManager parent) {
+               super("Open &Recent");
+               
+               this.window = window;
+               setParent(parent);
+               history = AppRecentFiles.getInstance();
+               add(empty = new EmptyAction());
+               addMenuListener(menuListener);
+       
+               ActionManager actions = window.getActions();
+               if (actions != null) {
+                       OpenAction openAction = actions.get(OpenAction.class);
+                       openAction.addPropertyChangeListener(actionListener);
+                       action = openAction;
+               }
+               
+               try {
+                       Properties props = window.getProperties();
+                       String icon = props.getProperty("AppRecentMenu.icon", 
+                               "file:icons/open-recent.png");
+                       setImageURL(new URL(icon));
+               } catch (MalformedURLException e) {
+                       // Ignore
+               }
+       }       
+       
+       @Override
+       public void fill(Menu parent, int index) {
+               super.fill(parent, index);
+               MenuItem item = getMenuItem();
+               if (item != null) {
+                       item.setEnabled(action.isEnabled());
+               }
+       }
+
+
+       private void buildMenu() {
+               removeAll();
+               
+               if (history.empty()) {
+                       add(empty);
+               } else {
+                       for (File file : history) {
+                               add(new OpenRecentAction(window.getActions(), file));
+                       }
+               }
+               
+               update(false);
+       }
+       
+       
+       private final class EmptyAction extends Action {
+               public EmptyAction() {
+                       setText("No Recent Files");
+                       setEnabled(false);
+               }
+       };
+       
+       
+       private final IMenuListener menuListener = new IMenuListener() {
+               public void menuAboutToShow(IMenuManager manager) {
+                       buildMenu();
+               }
+       };
+
+       
+       private final IPropertyChangeListener actionListener 
+               = new IPropertyChangeListener() {
+
+               public void propertyChange(PropertyChangeEvent event) {
+                       MenuItem item = getMenuItem();
+                       if (item != null) {
+                               item.setEnabled(action.isEnabled());
+                       }
+               }
+       };
+       
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/AppStatus.java b/Annotation/src/ie/dcu/apps/ist/AppStatus.java
new file mode 100644 (file)
index 0000000..b888e21
--- /dev/null
@@ -0,0 +1,46 @@
+package ie.dcu.apps.ist;
+
+import java.net.*;
+
+import org.eclipse.jface.resource.*;
+import org.eclipse.swt.graphics.*;
+
+/**
+ * Application status bar message type.
+ * 
+ * @author Kevin McGuinness
+ */
+public enum AppStatus {
+       Information, Warning, Error;
+       
+       public Image getIcon() {
+               String key = key();
+               Image image = JFaceResources.getImage(key);
+               if (image == null) {
+                       ImageRegistry registry = JFaceResources.getImageRegistry();
+                       ImageDescriptor descriptor = createImageDescriptor();
+                       registry.put(key, descriptor);
+                       image = registry.get(key);
+               }
+               return image;
+       }
+       
+       private ImageDescriptor createImageDescriptor() {
+               try {
+                       return ImageDescriptor.createFromURL(new URL(key()));
+               } catch (MalformedURLException e) {
+                       throw new RuntimeException(e);
+               }
+       }
+       
+       private String key() {
+               switch (this) {
+               case Information:
+                       return "file:resources/icons/dialog-information.png";
+               case Warning:
+                       return "file:resources/icons/dialog-warning.png";
+               default:
+                       return "file:resources/icons/dialog-error.png";
+               }
+       }
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/AppWindow.java b/Annotation/src/ie/dcu/apps/ist/AppWindow.java
new file mode 100644 (file)
index 0000000..5f32b24
--- /dev/null
@@ -0,0 +1,725 @@
+package ie.dcu.apps.ist;
+
+import ie.dcu.apps.ist.actions.*;
+import ie.dcu.apps.ist.event.*;
+import ie.dcu.apps.ist.exp.Experiment;
+import ie.dcu.apps.ist.views.*;
+import ie.dcu.segment.*;
+import ie.dcu.segment.annotate.*;
+import ie.dcu.swt.*;
+import ie.dcu.swt.event.*;
+import ie.dcu.swt.layout.LayoutFactory;
+import ie.dcu.util.*;
+
+import java.io.*;
+import java.net.*;
+import java.util.Properties;
+import java.util.logging.*;
+
+import org.eclipse.jface.action.*;
+import org.eclipse.jface.resource.*;
+import org.eclipse.jface.window.ApplicationWindow;
+import org.eclipse.swt.*;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.*;
+
+/**
+ * Main interactive segmentation tool application window.
+ * 
+ * @author Kevin McGuinness
+ */
+public class AppWindow extends ApplicationWindow implements FileDropListener {
+       private static final Logger log = Logger.getLogger("AppWindow");
+
+       private final Properties props;
+
+       private AppPrefsManager prefsManager;
+       private ActionManager actions;
+       private Composite content;
+       private SegmentationView view;
+       private Shell shell;
+       private ImageObserver observer;
+       private Experiment experiment;
+       private ExperimentPanel experimentPanel;
+       private boolean experimentModeEmbedded;
+
+
+       public AppWindow() {
+               super(null);
+
+               props = loadProperties();
+
+               addMenuBar();
+               addStatusLine();
+       }
+       
+       
+       @Override
+       protected boolean canHandleShellCloseEvent() {
+               if (!ExitAction.confirmExit(this)) {
+                       return false; 
+               }
+               return super.canHandleShellCloseEvent();
+       }
+
+
+       private Properties loadProperties() {
+               try {
+                       return Application.loadProperties(getPropertiesFile());
+               } catch (IOException e) {
+                       log.severe("Unable to load properties file " + e.getMessage());
+                       throw new RuntimeException(e);
+               }
+       }
+       
+       private String getPropertiesFile() {
+               return OsUtils.isMacOS() ? "application.mac" : "application";
+       }
+
+
+       public void updateWindowTitle() {
+               String title;
+               if (hasContext()) {
+                       String file = getContext().getFile().getName();
+                       title = String.format("%s [%s]", Application.APP_NAME, file);
+                       
+               } else {
+                       title = Application.APP_NAME;
+               }
+               
+               if (isExperimentMode()) {
+                       title += " - Experiment Mode";
+               }
+               
+               getShell().setText(title);
+       }
+
+
+       private SegmentationView createView(Composite parent) {
+
+               // Load props
+               Properties props;
+               try {
+                       props = Application.loadProperties("view"); 
+               } catch (IOException e) {
+                       log.severe("Error loading view properties " + e.getLocalizedMessage());
+                       throw new RuntimeException(e);
+               }
+
+               // Create view
+               SegmentationView view = new SegmentationView(props, parent, 0);
+
+               boolean blocksOnFork = false;
+               
+               // Set runnable context 
+               view.setRunnableContext(this, blocksOnFork);
+
+               // Add observer
+               observer = new ImageObserver(view);
+
+               // Return new view
+               return view;
+       }
+
+
+       private static ImageDescriptor createImageDescriptor(String url) {
+               try {
+                       return ImageDescriptor.createFromURL(new URL(url));
+               } catch (MalformedURLException e) {
+                       throw new RuntimeException(e);
+               }
+       }
+
+
+       private void updateEnabledActions() {
+               ActionManager a = getActions();
+               boolean ctxAvailable = hasContext();
+               boolean experimentMode = isExperimentMode();
+               
+               a.setEnabled(OpenAction.class, !experimentMode);
+               a.setEnabled(PreferencesAction.class, !experimentMode);
+               a.setEnabled(SaveAction.class, ctxAvailable && !experimentMode);
+               a.setEnabled(SaveAsAction.class, ctxAvailable && !experimentMode);
+               a.setEnabled(ExportViewAction.class, ctxAvailable && !experimentMode);
+               a.setEnabled(ExportTransparentPNGAction.class, ctxAvailable && !experimentMode);
+               a.setEnabled(PrintAction.class, ctxAvailable && !experimentMode);
+               a.setEnabled(CopyAction.class, ctxAvailable && !experimentMode);
+               a.setEnabled(UndoAction.class, ctxAvailable && view.canUndo());
+               a.setEnabled(RedoAction.class, ctxAvailable && view.canRedo());
+               a.setEnabled(NextAction.class, ctxAvailable && !experimentMode);
+               a.setEnabled(PreviousAction.class, ctxAvailable && !experimentMode);
+               a.setEnabled(OpenExperimentAction.class, !experimentMode);
+               
+               updateExportImageMapAction();
+               
+               if (experimentMode) {
+                       
+                       boolean changeSelection = false;
+                       
+                       // Enable experiment segmenters
+                       for (SelectSegmenterAction s : a.getSegmentationActions()) {
+                               Segmenter segmenter = s.getSegmenter();
+                               boolean enabled = experiment.using(segmenter);
+                               s.setEnabled(enabled);
+                               
+                               if (!s.isEnabled() && s.isChecked()) {
+                                       // The selected segmenter has been disabled,
+                                       // we need to select a different one
+                                       changeSelection = true;
+                                       s.setChecked(false);
+                               }
+                       }
+                       
+                       if (changeSelection) {
+                               // Select the first available segmenter
+                               for (SelectSegmenterAction s : a.getSegmentationActions()) {
+                                       if (experiment.using(s.getSegmenter())) {
+                                               s.setChecked(true);
+                                               s.run();
+                                               break;
+                                       }
+                               }
+                       }
+                       
+               } else {
+                       // Enable all select segmenter actions
+                       for (SelectSegmenterAction s : a.getSegmentationActions()) {
+                               s.setEnabled(true);
+                       }
+               }
+       }
+       
+       private void updateExportImageMapAction() {
+               ActionManager a = getActions();
+               SegmentationContext ctx = getContext();
+               
+               if (ctx != null && !isExperimentMode()) {
+                       AnnotationManager am = ctx.getAnnotations();
+                       boolean hasObject = am.hasForegroundAnnotation() 
+                               && am.hasBackgroundAnnotation();
+                       a.setEnabled(ExportImageMapAction.class, hasObject);
+               
+               } else {
+                       a.setEnabled(ExportImageMapAction.class, false);
+               }
+       }
+       
+       
+       private void updateUndoRedoActions() {
+               ActionManager a = getActions();
+               boolean ctxAvailable = hasContext();
+               a.setEnabled(UndoAction.class, ctxAvailable && view.canUndo());
+               a.setEnabled(RedoAction.class, ctxAvailable && view.canRedo());
+       }
+
+
+       @Override
+       protected void configureShell(Shell shell) {
+               this.shell = shell;
+               super.configureShell(shell);
+               updateWindowTitle();
+               loadIcons(shell);
+               shell.setSize(800, 600);
+               SwtUtils.center(shell);
+       }
+       
+       
+       private void loadIcons(Shell shell) {
+               final String[] icons = { 
+                               "resources/icons/icon-16.png",
+                               "resources/icons/icon-24.png",
+                               "resources/icons/icon-32.png",
+                               "resources/icons/icon-48.png"
+               };
+               
+               Image[] images = new Image[icons.length];
+               Display display = shell.getDisplay();
+               
+               try {
+                       int i = 0;
+                       for (String file : icons) {
+                               images[i++] = new Image(display, file);
+                       }
+                       
+                       shell.setImages(images);
+       
+               } catch (SWTException e) {
+                       log.warning("Error loading application window icons: " 
+                               + e.getLocalizedMessage());
+               }
+       }
+
+
+       @Override
+       protected Control createContents(Composite parent) {
+               content = new Composite(parent, SWT.NONE);
+
+               content.setLayout(LayoutFactory.createGridLayout(0, 0, 2, false));
+
+               view = createView(content);
+               view.setLayoutData(LayoutFactory.createGridData());
+               view.addContextChangeListener(contextListener);
+               
+               SwtUtils.createFileDropTarget(view, this);
+
+               // Done creating contents
+               getPrefsManager().update();
+               updateEnabledActions();
+
+               return content;
+       }
+
+
+       @Override
+       protected boolean showTopSeperator() {
+               return false;
+       }
+
+
+       @Override
+       protected MenuManager createMenuManager() {
+               MenuManager bar = new MenuManager();
+
+               ActionManager actions = getActions();
+
+               MenuManager file = addMenu(bar, "&File");
+               file.add(actions.get(OpenAction.class));
+               
+               file.add(new AppRecentMenu(this, file));
+               
+               file.add(new Separator());
+               file.add(actions.get(SaveAction.class));
+               file.add(actions.get(SaveAsAction.class));
+               file.add(new Separator());
+               
+               // Export menu ->
+               MenuManager exportMenu = addMenu(file, "&Export", 
+                       props.getProperty("ExportMenu.icon"));
+               
+               exportMenu.add(actions.get(ExportViewAction.class));
+               exportMenu.add(actions.get(ExportImageMapAction.class));
+               exportMenu.add(actions.get(ExportTransparentPNGAction.class));
+               
+               file.add(new Separator());
+               file.add(actions.get(PrintAction.class));
+               file.add(new Separator());
+               file.add(actions.get(ExitAction.class));
+
+               MenuManager edit = addMenu(bar, "&Edit");
+
+               edit.add(actions.get(UndoAction.class));
+               edit.add(actions.get(RedoAction.class));
+               edit.add(new Separator());
+               edit.add(actions.get(CopyAction.class));
+               edit.add(new Separator());
+               edit.add(actions.get(PreferencesAction.class));
+
+               MenuManager tools = addMenu(bar, "&Tools");
+               tools.add(actions.get(OpenExperimentAction.class));
+               tools.add(new Separator());
+               
+               for (SelectSegmenterAction a : actions.getSegmentationActions()) {
+                       tools.add(a);
+               }
+               
+               tools.add(new Separator());
+               tools.add(actions.get(ConfigureSegmenterAction.class));
+               
+               MenuManager go = addMenu(bar, "&Go");
+               go.add(actions.get(NextAction.class));
+               go.add(actions.get(PreviousAction.class));
+               
+               
+               MenuManager help = addMenu(bar, "&Help");
+
+               help.add(actions.get(HelpAction.class));
+               help.add(actions.get(AboutAction.class));
+               
+               if (OsUtils.isMacOSX()) {
+                       // Enhance the UI on the Mac
+                       IAction aboutAction = actions.get(AboutAction.class);
+                       IAction prefAction = actions.get(PreferencesAction.class);
+                       Listener quitListener = new Listener() {
+                               public void handleEvent(Event evt) {
+                                       getActions().get(ExitAction.class).runWithEvent(evt);
+                               }
+                       };
+                       CocoaUIEnhancer enhancer = new CocoaUIEnhancer(Application.APP_NAME);
+                       enhancer.hookApplicationMenu(Display.getDefault(), 
+                               quitListener, aboutAction, prefAction);
+               }
+
+               return bar;
+       }
+
+
+       protected static MenuManager addMenu(MenuManager parent, String text) {
+               MenuManager menu = new HoverMenuManager(text);
+               parent.add(menu);
+               return menu;
+       }
+       
+       protected static MenuManager addMenu(MenuManager parent, 
+                       String text, String image) {
+               
+               MenuManager menu;
+               try {
+                       menu = new HoverMenuManager(text, image != null ? 
+                               new URL(image) : null);
+               } catch (MalformedURLException e) {
+                       log.log(Level.WARNING, "Malformed URL", e);
+                       menu = new HoverMenuManager(text);
+               }
+               
+               parent.add(menu);
+               return menu;
+       }
+       
+       
+       
+       public void setExperiment(Experiment ex) {
+               if (experiment != ex) {
+                       experiment = ex;
+                       setContext(null);
+                       
+                       if (ex == null) {
+                               
+                               if (experimentPanel != null) {
+                                       experimentPanel.dispose();
+                                       experimentPanel = null;
+                                       content.layout();
+                               }
+                       } else {
+                       
+                               if (experimentModeEmbedded) {
+                                       experimentPanel = new ExperimentPanel(this, content, SWT.NONE);
+                                       GridData data = new GridData(SWT.FILL, SWT.FILL, false, true);
+                                       data.widthHint = 180;
+                                       data.verticalIndent = 5;
+                                       experimentPanel.setLayoutData(data);
+                                       content.layout();
+                                       
+                               } else {
+                                       ExperimentPanel.open(this);
+                               }
+                       }
+                       updateEnabledActions();
+                       updateWindowTitle();
+               }
+       }
+       
+       
+       public Experiment getExperiment() {
+               return experiment;
+       }
+
+
+       public boolean isExperimentMode() {
+               return experiment != null;
+       }
+
+
+       public void setExperimentModeEmbedded(boolean on) {
+               this.experimentModeEmbedded = on;
+       }
+
+
+       public AppPrefs getPrefs() {
+               return getPrefsManager().getPrefs();
+       }
+
+
+       AppPrefsManager getPrefsManager() {
+               if (prefsManager == null) {
+                       prefsManager = new AppPrefsManager(this);
+               }
+               return prefsManager;
+       }
+
+
+       public Properties getProperties() {
+               return props;
+       }
+
+
+       public ActionManager getActions() {
+               if (actions == null) {
+                       actions = new ActionManager(this);
+               }
+               return actions;
+       }
+
+
+       public Shell getShell() {
+               Shell shell = super.getShell();
+               if (shell == null) {
+                       return this.shell;
+               }
+               return shell;
+       }
+
+
+       public SegmentationView getView() {
+               return view;
+       }
+
+
+       public SegmentationContext getContext() {
+               if (view != null) {
+                       return view.getContext();
+               }
+               return null;
+       }
+
+
+       public File getContextFile() {
+               if (hasContextFile()) {
+                       return getContext().getFile();
+               }
+               return null;
+       }
+
+
+       public Image getIcon(String url) {
+               Image image = JFaceResources.getImage(url);
+               if (image == null) {
+                       ImageRegistry registry = JFaceResources.getImageRegistry();
+                       ImageDescriptor descriptor = createImageDescriptor(url);
+                       registry.put(url, descriptor);
+                       image = registry.get(url);
+               }
+               return image;
+       }
+
+
+       public boolean hasContext() {
+               if (view != null) {
+                       return view.getContext() != null;
+               }
+               return false;
+       }
+
+
+       public boolean hasContextFile() {
+               return getContext() != null ? getContext().hasContextFile() : false;
+       }
+
+
+       public void setEnableFeedback(boolean on) {
+               if (observer != null) {
+                       observer.setEnabled(on);
+               }
+       }
+
+
+       public void setContext(SegmentationContext ctx) {
+               if (ctx != null) {
+                       // Set a segmenter if one has not been set
+                       if (!view.hasSegmenter()) {
+                               SegmenterRegistry registry = SegmenterRegistry.getInstance();
+                               view.setSegmenter(registry.getDefault());
+                       }
+               }
+       
+               // Set context
+               view.setContext(ctx);
+               updateWindowTitle();
+       }
+
+
+       public void status(String message) {
+               setStatus(message);
+       }
+
+
+       public void status(String format, Object... args) {
+               setStatus(String.format(format, args));
+       }
+
+
+       public void status(Image image, String format, Object... args) {
+               StatusLineManager manager = getStatusLineManager();
+               if (manager != null) {
+                       manager.setMessage(image, String.format(format, args));
+               }
+       }
+
+
+       public void status(AppStatus s, String format, Object... args) {
+               if (format == null) {
+                       setStatus(null);
+
+               } else {
+                       StatusLineManager manager = getStatusLineManager();
+                       if (manager != null) {
+                               if (s == AppStatus.Error) {
+                                       manager.setErrorMessage(s.getIcon(), String.format(format, args));
+                               } else {
+                                       manager.setMessage(s.getIcon(), String.format(format, args));
+                               }
+                       }
+               }
+       }
+
+
+       public void drop(FileDropEvent evt) {
+               System.out.println("drop received");
+               for (File f : evt.files()) {
+                       if (isAcceptable(f)) {
+                               getActions().get(OpenAction.class).open(f);
+                               break;
+                       }
+               }
+       }
+
+
+       public boolean isAcceptable(File file) {
+               String ext = FileUtils.getExtension(file);
+               return (ext.equals(".ctx") || SwtUtils.getImageFormat(file) != -1);
+       }
+
+       
+       private void handleContextChanged(ContextChangedEvent evt) {
+               
+               // Remove listener from old context
+               if (evt.oldContext != null) {
+                       evt.oldContext.removeAnnotationListener(annotationListener);
+               }
+               
+               // Add listener to new context
+               if (evt.newContext != null) {
+                       evt.newContext.addAnnotationListener(annotationListener);
+               }
+               
+               // Update application state
+               updateEnabledActions();
+       }
+       
+       
+       private void handleAnnotationPerformed(AnnotationEvent e) {
+               
+               // Update state of undo and redo menu items
+               updateUndoRedoActions();
+               updateExportImageMapAction();
+       }
+       
+       
+       private final ContextChangeListener contextListener = new ContextChangeListener() {
+               public void contextChanged(ContextChangedEvent evt) {
+                       handleContextChanged(evt);
+               }
+       };
+       
+       
+       private final AnnotationListener annotationListener = new AnnotationAdapter() {
+               public void annotationsChanged(AnnotationEvent e) {
+                       handleAnnotationPerformed(e);
+               }               
+       };
+       
+       
+       private class ImageObserver implements MouseMoveListener, ContextChangeListener {
+               private static final String MONOSPACE_FONT = "Monospace";
+
+               private final ImageControl ctrl;
+               private ImageData image;
+               private boolean inside;
+               private boolean enabled;
+
+
+               public ImageObserver(SegmentationView view) {
+                       view.addContextChangeListener(this);
+                       view.getCanvas().addMouseMoveListener(this);
+                       ctrl = view.getImageControl();
+                       contextChanged(view.getContext());
+                       FontDescriptor fd = FontDescriptor.createFrom(MONOSPACE_FONT, 8, SWT.NORMAL);
+                       JFaceResources.getFontRegistry().put(MONOSPACE_FONT, fd.getFontData());
+               }
+
+
+               public void setEnabled(boolean enabled) {
+                       if (this.enabled != enabled) {
+                               status(null);
+                               Font font = JFaceResources.getDefaultFont();
+                               getStatusLineManager().getControl().setFont(font);
+                               this.inside = false;
+                               this.enabled = enabled;
+                       }
+               }
+
+
+               public boolean isEnabled() {
+                       return enabled;
+               }
+
+
+               public void mouseMove(MouseEvent e) {
+                       if (isEnabled()) {
+                               Point pt = getImagePoint(e);
+                               if (pt != null) {
+                                       inside(pt, getColor(pt));
+                               } else {
+                                       outside();
+                               }
+                       }
+               }
+
+
+               private void outside() {
+                       if (inside) {
+                               status(null);
+                               Font font = JFaceResources.getDefaultFont();
+                               getStatusLineManager().getControl().setFont(font);
+                               inside = false;
+                       }
+               }
+
+
+               private final Point getImagePoint(MouseEvent e) {
+                       if (image != null) {
+                               Point pt = new Point(e.x, e.y);
+                               if (ctrl.imageContains(pt)) {
+                                       return ctrl.canvasToImage(pt);
+                               }
+                       }
+                       return null;
+               }
+
+
+               private final RGB getColor(Point pt) {
+                               
+                       int pixel = image.getPixel(pt.x, pt.y);
+                       return image.palette.getRGB(pixel);
+               }
+
+
+               private void inside(Point pt, RGB c) {
+                       if (!inside) {
+                               Font font = JFaceResources.getFont(MONOSPACE_FONT);
+                               getStatusLineManager().getControl().setFont(font);
+                       }
+
+                       status(AppStatus.Information, 
+                                       "Location [%4d,%4d] Color [%3d,%3d,%3d]",
+                                       pt.x, pt.y, c.red, c.green, c.blue);
+                       
+                       inside = true;
+               }
+
+
+               public void contextChanged(ContextChangedEvent evt) {
+                       contextChanged(evt.newContext);
+               }
+
+
+               public void contextChanged(SegmentationContext ctx) {
+                       if (ctx != null) {
+                               image = ctx.getImageData();
+                       } else {
+                               image = null;
+                       }
+               }
+       }
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/Application.java b/Annotation/src/ie/dcu/apps/ist/Application.java
new file mode 100644 (file)
index 0000000..bbd3b38
--- /dev/null
@@ -0,0 +1,110 @@
+package ie.dcu.apps.ist;
+
+import ie.dcu.util.*;
+
+import java.io.*;
+import java.net.*;
+import java.security.*;
+import java.util.*;
+
+import static ie.dcu.util.FileUtils.pathJoin;
+import static ie.dcu.util.OsUtils.*;
+
+/**
+ * Base application. Contains information strings and methods to load
+ * application wide resources.
+ * 
+ * @author Kevin McGuinness
+ */
+public class Application {
+       public static final String APP_ID   = "ist";
+       public static final String APP_NAME = "Interactive Segmentation and Annotation Tool";
+       public static final String APP_VERSION  = "1.3.4";
+       public static final String APP_RESOURCE_DIR = "resources";
+       
+       /**
+        * Default locations to look for plugins
+        */
+       public static final String[] DEFAULT_PLUGIN_SEARCH_PATH 
+               = defaultPluginSearchPath();
+       
+       /**
+        * Loads a properties file from the application resource area
+        * (resources/config)
+        * 
+        * @param name
+        *        The properties file name. ".properties" will be appended if
+        *        necessary.
+        * @return A Properties object
+        * @throws IOException
+        *         If there is an error creating the Properties object.
+        */
+       public static Properties loadProperties(String name) throws IOException {
+               if (!name.endsWith(".properties")) {
+                       name = name + ".properties";
+               }
+               
+               String path = FileUtils.pathJoin(APP_RESOURCE_DIR, "config", name);
+               File file = new File(path);
+               System.out.println("Path:" + file);
+               return PropsUtils.load(file);
+       }
+       
+       /**
+        * Returns the users plugins folder
+        */
+       public static String userPluginsFolder() {
+               return pathJoin(userHome(), ".ist", "plugins");
+       }
+       
+       /**
+        * Returns the applications base folder
+        */
+       public static String applicationFolder() {
+               String apphome = System.getenv("IST_HOME");
+               if (apphome != null) {
+                       File file = new File(apphome);
+                       if  (file.isDirectory()) {
+                               return file.getAbsolutePath();
+                       }
+               } 
+               
+               ProtectionDomain domain = Application.class.getProtectionDomain();
+               CodeSource source = domain.getCodeSource();
+               URL location = source.getLocation();
+               String path = location.getPath();
+               try {
+                       
+                       path = URLDecoder.decode(path, "UTF-8");
+                       if (isWindows()) {
+                               path = path.substring(1);
+                       }
+                               
+                       path = new File(path).getParent();
+               } catch (UnsupportedEncodingException e) {
+                       path = System.getProperty("user.dir");
+               }
+                       
+               return path;
+       }
+       
+       public static String applicationPluginsFolder() {
+               return pathJoin(applicationFolder(), "plugins");
+       }
+       
+       public static String osxPluginSearchPath() {
+               return pathJoin(userHome(), "Library", 
+                       "Application Support", APP_NAME, "Plugins");
+       }
+       
+       private static String[] defaultPluginSearchPath() {
+               ArrayList<String> paths = new ArrayList<String>();
+               paths.add(userPluginsFolder());
+               if (isMacOSX()) {
+                       paths.add(osxPluginSearchPath());
+               }
+               paths.add(applicationPluginsFolder());
+               return paths.toArray(new String[paths.size()]);
+       }
+       
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/EvaluatorRegistry.java b/Annotation/src/ie/dcu/apps/ist/EvaluatorRegistry.java
new file mode 100644 (file)
index 0000000..d7bc7b4
--- /dev/null
@@ -0,0 +1,70 @@
+package ie.dcu.apps.ist;
+
+import ie.dcu.eval.*;
+
+import java.util.*;
+
+public class EvaluatorRegistry {
+       private static EvaluatorRegistry instance;
+       private final Set<Evaluator> evaluators;
+       
+       private EvaluatorRegistry() {
+               evaluators = new LinkedHashSet<Evaluator>();
+               init();
+       }
+       
+       
+       private void init() {
+               add(new ConfusionMatrixEvaluator());
+               add(new BoundaryAccuracyEvaluator());
+       }
+       
+       
+       public static EvaluatorRegistry getInstance() {
+               if (instance == null) {
+                       instance = new EvaluatorRegistry();
+               }
+               return instance;
+       }
+       
+       
+       public Evaluator find(String name) {
+               for (Evaluator e : evaluators) {
+                       
+                       // Check name
+                       String ename = e.getName();
+                       if (ename.equals(name)) {
+                               return e;
+                       }
+                       
+                       // Check class name
+                       String cname = e.getClass().getName();
+                       if (cname.equals(name)) {
+                               return e;
+                       }
+                       
+                       // Check simple name
+                       String sname = e.getClass().getSimpleName();
+                       if (sname.equals(name)) {
+                               return e;
+                       }
+               }
+               
+               return null;
+       }
+       
+       
+       public void add(Evaluator evaluator) {
+               evaluators.add(evaluator);
+       }
+       
+       
+       public Set<Evaluator> evaluators() {
+               return Collections.unmodifiableSet(evaluators);
+       }
+
+
+       public Iterator<Evaluator> iterator() {
+               return evaluators.iterator();
+       }
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/Main.java b/Annotation/src/ie/dcu/apps/ist/Main.java
new file mode 100644 (file)
index 0000000..d878efd
--- /dev/null
@@ -0,0 +1,119 @@
+package ie.dcu.apps.ist;
+
+import ie.dcu.plugin.*;
+import ie.dcu.segment.Segmenter;
+
+import java.util.logging.Logger;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.*;
+
+/**
+ * Application launcher.
+ * 
+ * @author Kevin McGuinness
+ */
+public class Main {
+       public static final Logger log = Logger.getLogger("Main");
+       
+       /**
+        * Message to show when GDI+ is not installed.
+        */
+       private static final String NO_GDIPLUS = 
+               "Unable to load required library: GDI+ (gdiplus.dll)\n\n" +
+               "The GDI+ library needs to be installed before this program " +
+               "can be used on this platform. See the note at the end of " +
+               "the download page for further details.";
+               
+       
+       public static void main(String[] args) {
+               System.out.print(Application.DEFAULT_PLUGIN_SEARCH_PATH);
+               for (String s: Application.DEFAULT_PLUGIN_SEARCH_PATH) {
+                       System.out.println(s);
+               }
+
+               Display.setAppName(Application.APP_NAME);
+               check();
+               loadPlugins();
+               AppWindow window = new AppWindow();
+               window.setBlockOnOpen(true);
+               window.open();
+               System.exit(0);
+       }
+       
+       private static void loadPlugins() {
+               PluginManager manager = new PluginManager();
+               for (String path : Application.DEFAULT_PLUGIN_SEARCH_PATH) {
+                       manager.searchPath().add(path);
+               }
+               manager.loadPlugins();
+               for (Plugin plugin : manager.plugins()) {
+                       String classname = plugin.getMetadata("segmenter");
+                       if (classname != null) {
+                               loadSegmenterPlugin(plugin, classname);
+                       }
+               }
+       }
+
+       private static void loadSegmenterPlugin(Plugin plugin, String classname) {
+               try {
+                       Segmenter segmenter = (Segmenter) 
+                               plugin.loadObject(classname);
+                       
+                       SegmenterRegistry.getInstance().add(segmenter);
+                       
+               } catch (PluginException e) {
+                       log.severe("Unable to load plugin: " + e);
+               }
+       }
+
+       public static boolean contains(String[] args, String argument) {
+               for (String arg : args) {
+                       while (arg.startsWith("-")) {
+                               arg = arg.substring(1);
+                       }
+                       
+                       if (arg.equals(argument)) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+       
+       private static void check() {
+               // Check for potential missing GDI+ on Win2K, NT, ME 98
+               String os = System.getProperty("os.name");
+               if (os.equals("Windows 2000") ||
+                       os.equals("Windows NT") ||
+                       os.equals("Windows ME") ||
+                       os.equals("Windows 98")) 
+               {
+                       try {
+                               System.loadLibrary("gdiplus");
+                       } catch (RuntimeException e) {
+                               exit(NO_GDIPLUS);
+                       }
+               }
+       }
+       
+       static void exit(String message) {
+               Display display = Display.getDefault();
+               Rectangle rect = display.getBounds();
+               
+               Shell shell = display.getActiveShell();
+               if (shell == null) {
+                       shell = new Shell(display, SWT.NO_TRIM);
+                       shell.setBounds(rect.width/2, rect.height/2, 0, 0);
+                       shell.open();
+                       shell.setText("Error");
+               }
+               
+               MessageBox box = new MessageBox(shell, SWT.ICON_ERROR);
+               box.setText("Error");
+               box.setMessage(message);
+               box.open();
+               display.dispose();
+               System.exit(1);
+       }
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/PainterRegistry.java b/Annotation/src/ie/dcu/apps/ist/PainterRegistry.java
new file mode 100644 (file)
index 0000000..b115e2f
--- /dev/null
@@ -0,0 +1,47 @@
+package ie.dcu.apps.ist;
+
+import ie.dcu.segment.painters.*;
+
+import java.util.*;
+
+public class PainterRegistry {
+       private final LinkedHashMap<String, SegmentationPainter> painters;
+
+       public PainterRegistry() {
+               painters = new LinkedHashMap<String, SegmentationPainter>();
+               init();
+       }
+       
+       
+       private void init() {
+               add(new CombinedPainter());
+               add(new OriginalPainter());
+               add(new MarkupPainter());
+               add(new MaskPainter());
+               add(new ForegroundOnlyPainter());
+               add(new OutlineOverlayPainter());
+               add(new LabelPainter());
+       }
+       
+       
+       public void add(SegmentationPainter painter) {
+               painters.put(painter.getName(), painter);
+       }
+       
+       
+       public SegmentationPainter get(String painter) {
+               return painters.get(painter);
+       }
+       
+       
+       public Collection<SegmentationPainter> values() {
+               return painters.values();
+       }
+       
+       
+       public void dispose() {
+               for (SegmentationPainter p : values()) {
+                       p.dispose();
+               }
+       }
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/SegmenterRegistry.java b/Annotation/src/ie/dcu/apps/ist/SegmenterRegistry.java
new file mode 100644 (file)
index 0000000..f3fec09
--- /dev/null
@@ -0,0 +1,107 @@
+package ie.dcu.apps.ist;
+
+import ie.dcu.segment.*;
+
+import java.util.*;
+
+/**
+ * Registry for segmenters.
+ * 
+ * @author Kevin McGuinness
+ */
+public class SegmenterRegistry implements Iterable<Segmenter> {
+       private static final String DEFAULT_SEGMENTER_NAME = "IgcSegmenter";
+       private static SegmenterRegistry instance;
+       private final Set<Segmenter> segmenters;
+       
+       private SegmenterRegistry() {
+               segmenters = new LinkedHashSet<Segmenter>();
+               init();
+       }
+       
+       
+       private void init() {
+               // OutlineSegmenter is not very useful
+               // add(new OutlineSegmenter());
+               
+               // Geodesic Active Contours is too sensitive to parameters
+               // for general use on natural images.
+               // add(new SeededGacSegmenter());
+               
+               //add(new SrgSegmenter());
+               //add(new IgcSegmenter());
+               //add(new BptSegmenter());
+               //add(new SioxSegmenter());
+               //add(new SpatiogramSegmenter());
+       }
+
+
+       public static SegmenterRegistry getInstance() {
+               if (instance == null) {
+                       instance = new SegmenterRegistry();
+               }
+               return instance;
+       }
+       
+       
+       public Segmenter find(String name) {
+               for (Segmenter s : segmenters) {
+                       
+                       // Check name
+                       String ename = s.getName();
+                       if (ename.equals(name)) {
+                               return s;
+                       }
+                       
+                       // Check class name
+                       String cname = s.getClass().getName();
+                       if (cname.equals(name)) {
+                               return s;
+                       }
+                       
+                       // Check simple name
+                       String sname = s.getClass().getSimpleName();
+                       if (sname.equals(name)) {
+                               return s;
+                       }
+               }
+               
+               return null;
+       }
+       
+       
+       public boolean isDefault(Segmenter s) {
+               if (s != null) {
+                       if (segmenters.size() == 1 && segmenters.contains(s)) {
+                               return true;
+                       }
+                       return s.getClass().getSimpleName().equals(DEFAULT_SEGMENTER_NAME);
+               }
+               return false;
+       }
+       
+       
+       public Segmenter getDefault() {
+               for (Segmenter s : segmenters) {
+                       if (isDefault(s)) {
+                               return s;
+                       }
+               }
+               return null;
+       }
+       
+       
+       public void add(Segmenter segmenter) {
+               segmenters.add(segmenter);
+       }
+       
+       
+       public Set<Segmenter> segmenters() {
+               return Collections.unmodifiableSet(segmenters);
+       }
+
+
+       public Iterator<Segmenter> iterator() {
+               return segmenters.iterator();
+       }
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/actions/AboutAction.java b/Annotation/src/ie/dcu/apps/ist/actions/AboutAction.java
new file mode 100644 (file)
index 0000000..be5d61f
--- /dev/null
@@ -0,0 +1,109 @@
+package ie.dcu.apps.ist.actions;
+
+import ie.dcu.apps.ist.Application;
+import ie.dcu.swt.layout.LayoutFactory;
+
+import org.eclipse.jface.dialogs.*;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.*;
+
+
+/**
+ * Show an about dialog.
+ * 
+ * @author Kevin McGuinness
+ */
+public class AboutAction extends AppAction {
+       
+       private AboutBox dialog;
+       
+       public AboutAction(ActionManager m) {
+               super(m);
+       }
+
+       
+       @Override 
+       public void run() { 
+               if (dialog == null) {
+                       dialog = new AboutBox();
+               }
+               dialog.open();
+       }
+       
+       
+       private class AboutBox extends Dialog {
+               
+               private static final String MESSAGE = 
+                       "   Kevin McGuinness <a href=\"mailto:kevin.mcguinness@eeng.dcu.ie\">" +
+                       "kevin.mcguinness@eeng.dcu.ie</a>\n" +
+                       "   Center for Digital Video Processing\n" +
+                       "   Dublin City University.\n" +
+                       "   <a href=\"http://www.cdvp.dcu.ie\">http://www.cdvp.dcu.ie</a>";
+               
+               
+               private Composite composite;
+               
+
+               protected AboutBox() {
+                       super(window);
+               }
+               
+
+               @Override
+               protected Control createDialogArea(Composite parent) {
+                       composite = new Composite(parent, SWT.NONE);
+                       composite.setLayout(LayoutFactory.createGridLayout(5, 5));
+                       
+                       String image = string("aboutImage");
+                       addImage(image);
+                       addLabel(String.format("Version %s", Application.APP_VERSION), SWT.CENTER);
+                       addLabel(" SWT Version " + swtVersionString(), SWT.CENTER);
+                       addLabel(" Developed By:", SWT.LEFT);
+                       addLink(MESSAGE);
+               
+                       return composite;
+               }
+               
+               private String swtVersionString() {
+                       return String.format("%d (%s)", SWT.getVersion(), SWT.getPlatform());
+               }
+       
+               
+               @Override
+               protected void createButtonsForButtonBar(Composite parent) {
+                       createButton(parent, 
+                                       IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
+               }
+
+
+               @Override
+               protected void configureShell(Shell shell) {
+                       super.configureShell(shell);
+                       shell.setText("About");
+               }
+               
+               
+               private void addLink(String string) {
+                       Link link = new Link(composite, 0);
+                       link.setText(string);
+                       link.setLayoutData(LayoutFactory.createGridData());
+               }
+
+               
+               private void addLabel(String text, int alignment) {
+                       Label label = new Label(composite, 0);
+                       label.setText(text);
+                       label.setAlignment(alignment);
+                       label.setLayoutData(LayoutFactory.createGridData());
+                       label.setFont(JFaceResources.getBannerFont());
+               }
+               
+               private void addImage(String url) {
+                       Label label = new Label(composite, 0);
+                       label.setImage(window.getIcon(url));
+                       label.setLayoutData(LayoutFactory.createGridData());
+               }
+       }
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/actions/ActionManager.java b/Annotation/src/ie/dcu/apps/ist/actions/ActionManager.java
new file mode 100644 (file)
index 0000000..b1897f8
--- /dev/null
@@ -0,0 +1,133 @@
+package ie.dcu.apps.ist.actions;
+
+import ie.dcu.apps.ist.*;
+import ie.dcu.segment.Segmenter;
+import ie.dcu.util.OsUtils;
+
+import java.io.IOException;
+import java.util.*;
+import java.util.logging.Logger;
+
+/**
+ * Manages application actions.
+ * 
+ * @author Kevin McGuinness
+ */
+public class ActionManager {
+       private static final Logger log = Logger.getLogger("ActionManager");
+       
+       private final AppWindow window;
+       private final Map<String, AppAction> actions;
+       private ArrayList<SelectSegmenterAction> segmenterActions;
+       private Properties props;
+       
+       
+       public ActionManager(AppWindow window) {
+               
+               this.window = window;
+               this.actions = new HashMap<String, AppAction>();
+               
+               try {
+                       this.props = Application.loadProperties(getPropertiesFile());
+               } catch (IOException e) {
+                       log.severe("Error loading action properties: " + 
+                                       e.getLocalizedMessage());
+                       throw new RuntimeException(e);
+               }
+               
+               init();
+       }
+       
+       
+       private String getPropertiesFile() {
+               return OsUtils.isMacOS() ? "actions.mac" : "actions";
+       }
+       
+       
+       Properties getProperties() {
+               return props;
+       }
+       
+       
+       AppWindow getWindow() {
+               return window;
+       }
+       
+
+       public void init() {
+               add(new OpenAction(this));
+               add(new SaveAction(this));
+               add(new SaveAsAction(this));
+               add(new AboutAction(this));
+               add(new CopyAction(this));
+               add(new ExitAction(this));
+               add(new ExportViewAction(this));
+               add(new ExportImageMapAction(this));
+               add(new ExportTransparentPNGAction(this));
+               add(new HelpAction(this));
+               add(new PreferencesAction(this));
+               add(new PrintAction(this));
+               add(new RedoAction(this));
+               add(new UndoAction(this));
+               add(new NextAction(this));
+               add(new PreviousAction(this));
+               add(new OpenExperimentAction(this));
+               add(new ConfigureSegmenterAction(this));
+               
+               // Add select segmenter actions
+               SegmenterRegistry registry = SegmenterRegistry.getInstance();
+               for (Segmenter s : registry) {
+                       add(new SelectSegmenterAction(this, registry, s));
+               }
+       }
+       
+       
+       public void add(AppAction action) {
+               actions.put(action.id(), action);
+       }
+       
+       
+       public <T extends AppAction> T get(Class<T> clazz) {
+               return clazz.cast(actions.get(id(clazz)));
+       } 
+       
+       
+       public <T extends AppAction> T get(Class<T> clazz, String id) {
+               return clazz.cast(actions.get(id));
+       }
+       
+       
+       public void setEnabled(String id, boolean enabled) {
+               AppAction action = actions.get(id);
+               if (action != null) {
+                       action.setEnabled(enabled);
+               }
+       }
+       
+       
+       public <T extends AppAction> void setEnabled(Class<T> clazz, boolean enabled) {
+               AppAction action = get(clazz);
+               if (action != null) {
+                       action.setEnabled(enabled);
+               }
+       }
+       
+       
+       public Collection<SelectSegmenterAction> getSegmentationActions() {
+               if (segmenterActions == null) {
+                       segmenterActions = new ArrayList<SelectSegmenterAction>();
+                       for (AppAction a : actions.values()) {
+                               if (a instanceof SelectSegmenterAction) {
+                                       segmenterActions.add((SelectSegmenterAction) a);
+                               }
+                       }
+               }
+               
+               return Collections.unmodifiableCollection(segmenterActions);
+       }
+       
+       
+       private String id(Class<?> clazz) {
+               return clazz.getName();
+       }
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/actions/AppAction.java b/Annotation/src/ie/dcu/apps/ist/actions/AppAction.java
new file mode 100644 (file)
index 0000000..a5a11a8
--- /dev/null
@@ -0,0 +1,122 @@
+package ie.dcu.apps.ist.actions;
+
+import java.util.logging.*;
+
+import org.eclipse.jface.dialogs.*;
+import org.eclipse.swt.graphics.*;
+
+import ie.dcu.apps.ist.*;
+
+/**
+ * Root class for all application actions.
+ * 
+ * @author Kevin McGuinness
+ */
+public class AppAction extends ConfiguredAction {
+       
+       // Make easier for subclasses to set status
+       protected static final AppStatus Information = AppStatus.Information;
+       protected static final AppStatus Warning = AppStatus.Warning;
+       protected static final AppStatus Error = AppStatus.Error;
+       
+       // Logger
+       protected final Logger log = Logger.getLogger(getClass().getSimpleName());
+       
+       // Window
+       protected final AppWindow window;
+       
+       // Action manager
+       protected final ActionManager manager;
+       
+
+       public AppAction(ActionManager m) {
+               super(m.getProperties());
+               manager = m;
+               window = m.getWindow();
+       }
+       
+       
+       public AppAction(ActionManager m, int style) {
+               super(m.getProperties(), style);
+               manager = m;
+               window = m.getWindow();
+       }
+       
+       
+       @Override
+       public void arm() {
+               super.arm();
+               status(AppStatus.Information, getDescription());
+       }
+
+
+       @Override
+       public void disarm() {
+               super.disarm();
+               window.setStatus(null);
+       }
+
+
+       public String id() {
+               return getClass().getName();
+       }
+       
+       
+       protected Image icon(String key) {
+               String prop = string(key);
+               if (prop != null) {
+                       return window.getIcon(prop);
+               }
+               return null;
+       }
+
+
+       protected void error(String message) {
+               MessageDialog.openError(window.getShell(), "Error", message);
+       }
+
+
+       protected void error(String format, Object... args) {
+               error(String.format(format, args));
+       }
+
+
+       protected void warning(String message) {
+               MessageDialog.openWarning(window.getShell(), "Warning", message);
+       }
+
+
+       protected void warning(String format, Object... args) {
+               warning(String.format(format, args));
+       }
+
+
+       protected void info(String message) {
+               MessageDialog.openInformation(window.getShell(), "Information", message);
+       }
+
+
+       protected void info(String format, Object... args) {
+               info(String.format(format, args));
+       }
+
+
+       protected void log(Level level, String message, Throwable th) {
+               log.log(level, message, th);
+       }
+
+
+       protected String property(String key) {
+               return properties.getProperty(key);
+       }
+
+
+       protected void status(AppStatus s, String format, Object... args) {
+               window.status(s, format, args);
+       }
+
+
+       protected void status(String format, Object... args) {
+               status(Information, format, args);
+       }
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/actions/ConfigureSegmenterAction.java b/Annotation/src/ie/dcu/apps/ist/actions/ConfigureSegmenterAction.java
new file mode 100644 (file)
index 0000000..5221928
--- /dev/null
@@ -0,0 +1,24 @@
+package ie.dcu.apps.ist.actions;
+
+import ie.dcu.apps.ist.views.SegmentationView;
+
+/**
+ * Show the configure segmenter dialog.
+ * 
+ * @author Kevin McGuinness
+ */
+public class ConfigureSegmenterAction extends AppAction {
+
+       public ConfigureSegmenterAction(ActionManager m) {
+               super(m);
+       }
+
+       
+       @Override 
+       public void run() { 
+               SegmentationView view = window.getView();
+               if (view.canShowOptions()) {
+                       view.showSegmenterOptions();
+               }
+       }
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/actions/ConfiguredAction.java b/Annotation/src/ie/dcu/apps/ist/actions/ConfiguredAction.java
new file mode 100644 (file)
index 0000000..24a33f0
--- /dev/null
@@ -0,0 +1,169 @@
+package ie.dcu.apps.ist.actions;
+
+import java.net.*;
+import java.util.*;
+import java.util.logging.*;
+
+import org.eclipse.jface.action.*;
+import org.eclipse.jface.resource.*;
+
+/**
+ * Hover Action configured from a properties file.
+ * 
+ * @author Kevin McGuinness
+ */
+public class ConfiguredAction extends HoverAction {
+       private static final Logger log = Logger.getLogger("ConfiguredAction");
+       
+       protected final Properties properties;
+       private final String id;
+       
+       
+       public ConfiguredAction(Properties properties) {
+               this(properties, null, AS_PUSH_BUTTON);
+       }
+       
+       
+       public ConfiguredAction(Properties properties, int style) {
+               this(properties, null, style);
+       }
+       
+       
+       public ConfiguredAction(Properties properties, String id, int style) {
+               super(null, style);
+               
+               assert (properties != null);
+               this.properties = properties;
+               
+               if (id != null) {
+                       this.id = id;
+               } else {
+                       this.id = getClass().getSimpleName();
+               }
+               
+               configure();
+       }
+
+       
+       private void configure() {
+               
+               // Set id
+               setId(id);
+
+               // Set text
+               setText(string("text"));
+               
+               // Set description
+               String description;
+               if ((description = string("description")) != null) {
+                       setDescription(description);
+               }
+               
+               // Set tooltip
+               String tooltip;
+               if ((tooltip = string("tooltip")) != null) {
+                       setToolTipText(tooltip);
+               }
+               
+               // Set accelerator
+               Integer keycode;
+               if ((keycode = accelerator("accelerator")) != null) {
+                       setAccelerator(keycode);
+               }
+       
+               // Set images
+               ImageDescriptor im;
+               
+               if ((im = image("image")) != null) {
+                       setImageDescriptor(im);
+               }
+               
+               if ((im = image("hoverImage")) != null) {
+                       setHoverImageDescriptor(im);
+               }
+               
+               if ((im = image("disabledImage")) != null) {
+                       setDisabledImageDescriptor(im);
+               }
+               
+               // Set status
+               Boolean status;
+               
+               if ((status = bool("checked") != null)) {
+                       setChecked(status);
+               }
+               
+               if ((status = bool("enabled") != null)) {
+                       setEnabled(status);
+               }
+       }
+       
+       
+       protected final Integer accelerator(String key) {
+               String value = string(key);
+               
+               if (value == null) {
+                       return null;
+               }
+               
+               int code = Action.convertAccelerator(value);
+               
+               if (code == 0) {
+                       log.warning("No accelerator: " + value);
+                       return null;
+               }
+               
+               if (code == -1) {
+                       log.warning("Not a valid accelerator keycode: " + value);
+                       return null;
+               }
+               
+               return code;
+       }
+       
+       
+       protected final Boolean bool(String key) {
+               String value = string(key);
+               
+               if (value == null) {
+                       return null;
+               }
+               
+               if (value.trim().equals("true")) {
+                       return true;
+               } else if (value.trim().equals("false")) {
+                       return false;
+               } else {
+                       log.warning("Not a boolean value: " + value);
+                       return null;
+               }
+       }
+       
+       
+       protected final ImageDescriptor image(String key) {
+               String url = string(key);
+               
+               if (url == null) {
+                       return null;
+               }
+               
+               try {
+                       return ImageDescriptor.createFromURL(new URL(url));
+                       
+               } catch (MalformedURLException e) {
+                       log.warning("Invalid URL for image " + url);
+                       return null;
+               }
+       }
+       
+       
+       protected final String string(String key) {
+               return properties.getProperty(key(key));
+       }
+       
+       
+       protected final String key(String name) {
+               return String.format("action.%s.%s", id, name);
+       }
+
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/actions/CopyAction.java b/Annotation/src/ie/dcu/apps/ist/actions/CopyAction.java
new file mode 100644 (file)
index 0000000..1e7eb65
--- /dev/null
@@ -0,0 +1,100 @@
+package ie.dcu.apps.ist.actions;
+
+import ie.dcu.apps.ist.views.SegmentationView;
+import ie.dcu.segment.SegmentationContext;
+import ie.dcu.segment.painters.SegmentationPainter;
+import ie.dcu.swt.*;
+
+import java.awt.Toolkit;
+import java.awt.datatransfer.*;
+import java.awt.image.BufferedImage;
+
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * Copy view to clipboard.
+ * 
+ * @author Kevin McGuinness
+ */
+public class CopyAction extends AppAction {
+       
+       public CopyAction(ActionManager m) {
+               super(m);
+       }
+
+       @Override 
+       public void run() { 
+               
+               if (window.hasContext()) {
+                       copy();
+               }
+       }
+
+       
+       private void copy() {
+               setClipboard(paintContext());
+               status("View copied to clipboard as image");
+       }
+       
+       
+       private static BufferedImage convert(Image image) {
+               BufferedImage im = ImageConverter.convert(image.getImageData());
+               image.dispose();
+               return im;
+       }
+
+
+       public void setClipboard(Image image) {
+               ImageSelection selection = new ImageSelection(convert(image));
+               Clipboard clip = Toolkit.getDefaultToolkit().getSystemClipboard();
+               clip.setContents(selection, null);
+       }
+       
+       
+       
+       private Image paintContext() {
+               SegmentationView view = window.getView();
+               SegmentationContext ctx = window.getContext();
+               SegmentationPainter painter = view.getPainter();
+               ObservableImage im = createCompatibleImage(ctx);
+               painter.paint(ctx, im);
+               return im.getImage();
+       }
+       
+       
+       private ObservableImage createCompatibleImage(SegmentationContext ctx) {
+               Image im = new Image(Display.getCurrent(), ctx.getBounds());
+               return new ObservableImage(im);
+       }
+       
+       
+       private static class ImageSelection implements Transferable {
+               private BufferedImage image;
+
+               
+               public ImageSelection(BufferedImage image) {
+                       this.image = image;
+               }
+
+
+               public DataFlavor[] getTransferDataFlavors() {
+                       return new DataFlavor[] { DataFlavor.imageFlavor };
+               }
+
+
+               public boolean isDataFlavorSupported(DataFlavor flavor) {
+                       return DataFlavor.imageFlavor.equals(flavor);
+               }
+
+
+               public Object getTransferData(DataFlavor flavor) 
+                       throws UnsupportedFlavorException
+               {
+                       if (!DataFlavor.imageFlavor.equals(flavor)) {
+                               throw new UnsupportedFlavorException(flavor);
+                       }
+                       return image;
+               }
+       }
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/actions/ExitAction.java b/Annotation/src/ie/dcu/apps/ist/actions/ExitAction.java
new file mode 100644 (file)
index 0000000..e6ee5c2
--- /dev/null
@@ -0,0 +1,37 @@
+package ie.dcu.apps.ist.actions;
+
+import ie.dcu.apps.ist.*;
+
+import org.eclipse.jface.dialogs.MessageDialog;
+
+/**
+ * Terminate the application.
+ * 
+ * @author Kevin McGuinness
+ */
+public class ExitAction extends AppAction {
+       public ExitAction(ActionManager m) {
+               super(m);
+       }
+
+       @Override 
+       public void run() {
+               if (confirmExit(window)) {
+                       window.close();
+                       System.exit(0);
+               }
+       }
+       
+       public static boolean confirmExit(AppWindow window) {
+               boolean confirm = window.getPrefs().get(
+                               Boolean.class, AppPrefs.Keys.CONFIRM_EXIT, true);
+               
+               if (confirm) {
+                       return MessageDialog.openConfirm(
+                                       window.getShell(), "Confirm", 
+                                       "Really exit the application?");
+               }
+               
+               return true;
+       }
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/actions/ExportImageMapAction.java b/Annotation/src/ie/dcu/apps/ist/actions/ExportImageMapAction.java
new file mode 100644 (file)
index 0000000..3efe020
--- /dev/null
@@ -0,0 +1,89 @@
+package ie.dcu.apps.ist.actions;
+
+import ie.dcu.apps.ist.dialogs.ExportDialog;
+import ie.dcu.apps.ist.export.imagemap.*;
+import ie.dcu.apps.ist.views.*;
+import ie.dcu.segment.*;
+import ie.dcu.swt.ImageConverter;
+
+import java.awt.image.BufferedImage;
+import java.io.*;
+import java.util.logging.Level;
+
+import org.eclipse.swt.program.Program;
+
+/**
+ * Export segmentation results as HTML image maps
+ * 
+ * @author Kevin McGuinness
+ */
+public class ExportImageMapAction extends AppAction{
+
+       public ExportImageMapAction(ActionManager m) {
+               super(m);
+       }
+
+       @Override 
+       public void run() { 
+               
+               if (window.hasContext()) {
+                       
+                       // Get options from user
+                       ExportDialog dialog = new ExportDialog(window.getShell());
+                       ExportDialog.Result result = dialog.open();
+                       
+                       if (result != null) {
+                               
+                               // Grab image and mask
+                               SegmentationContext ctx = window.getContext();
+                               SegmentationMask mask = ctx.getMask();
+                               BufferedImage image = ImageConverter.convert(ctx.getImageData());
+                               
+                               // Setup exporter
+                               Exporter exporter = new Exporter(image, mask);
+                               exporter.setEffect(result.effect);
+                               exporter.setHtmlFile(result.html);
+                               exporter.setImageFile(result.image);
+                               exporter.setObjectLink(result.link);
+                               exporter.setExportShape(result.shape);
+                               exporter.setObjectDescription(result.description);
+                               String label = SegmentationView.comboLabel.getText();
+                       if(label.indexOf('{') != -1)
+                       {
+                               label = label.substring(0,label.indexOf('{')-1);
+                       }
+                       exporter.setTitle(label);
+                               
+                               // Export
+                               try {
+                                       exporter.export(result.folder);
+                               } catch (IOException e) {
+                                       handleError(e);
+                                       return;
+                               } catch (ExportException e) {
+                                       handleError(e);
+                                       return;
+                               } 
+                               // for opening the image after saving as ImageMap
+                               if (result.open) {
+                                       File file = new File(result.folder, result.html);
+                                       Program program = Program.findProgram(".html");
+                                       if (program != null) {
+                                               program.execute(file.getAbsolutePath());
+                                       }
+                               }
+                       }
+               }
+       }
+       
+       private void handleError(Exception e) {
+               log(Level.WARNING, "Error exporting view as HTML image map", e);
+               
+               // Show error dialog
+               error("Error exporting view as HTML image map: %s",  
+                               e.getLocalizedMessage());
+               
+               // Set status message
+               status(Error, "Error exporting view as HTML image map");
+       }
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/actions/ExportTransparentPNGAction.java b/Annotation/src/ie/dcu/apps/ist/actions/ExportTransparentPNGAction.java
new file mode 100644 (file)
index 0000000..1315e33
--- /dev/null
@@ -0,0 +1,148 @@
+package ie.dcu.apps.ist.actions;
+
+import ie.dcu.segment.*;
+import ie.dcu.swt.SwtUtils;
+import ie.dcu.util.FileUtils;
+
+import java.io.*;
+import java.util.logging.Level;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.widgets.FileDialog;
+
+public class ExportTransparentPNGAction extends AppAction {
+       
+private static final String DEFAULT_SUFFIX = ".png";
+       
+       private FileDialog dialog;
+       private String directory;
+
+       public ExportTransparentPNGAction(ActionManager m) {
+               super(m);
+       }
+       
+       @Override 
+       public void run() { 
+               if (window.hasContext()) {
+                       File file = getFile();
+                       if (file != null) {
+                               directory = file.getParent();
+                               export(file);
+                       }
+               }               
+       }
+
+
+       private void export(File file) {
+               ImageData im = createSemiTransparentImage();
+               try {
+                       SwtUtils.saveImage(im, file);
+               } catch (IOException e) {
+                       handleError(file, e);
+               }
+       }
+       
+       
+       private ImageData createSemiTransparentImage() {
+               SegmentationContext ctx = window.getContext();
+               ImageData image = ctx.getImageData();
+               SegmentationMask mask = ctx.getMask();
+               ImageData result = new ImageData(image.width, image.height, 32, image.palette);
+               
+               int[] pixels = new int[image.width];
+               byte[] alphas = new byte[image.width];
+               
+               for (int y = 0; y < image.height; y++) {
+                       image.getPixels(0, y, image.width, pixels, 0);
+                       
+                       int offset = y * mask.cols;
+                       for (int i = 0; i < mask.cols; i++) {
+                               if (mask.values[i+offset] == SegmentationMask.BACKGROUND) {
+                                       alphas[i] = (byte) 0x00;
+                               } else {
+                                       alphas[i] = (byte) 0xff;
+                               }
+                       }
+                       
+                       result.setPixels(0, y, image.width, pixels, 0);
+                       result.setAlphas(0, y, image.width, alphas, 0);
+               }
+               
+               return result;
+       }
+
+       
+       private void handleError(File file, IOException e) {
+               // Log
+               log(Level.WARNING, "Error exporting view as image", e);
+               
+               // Show error dialog
+               error("Error exporting view as image %s: %s", 
+                               file.getName(), e.getLocalizedMessage()
+               );
+               
+               // Set status message
+               status(Error, "Error exporting view as image %s", file.getName());
+       }
+
+       
+       private File getFile() {
+               createExportDialog();
+               
+               String path = dialog.open();
+               if (path != null) {
+                       return checkFile(path);
+               }
+               
+               return null;
+       }
+       
+       
+       private File checkFile(String path) {
+               File file = new File(path);
+
+               if (SwtUtils.getImageFormat(file) != -1) {
+                       return file;
+               } 
+               
+               // Unknown file extension, so assume jpg
+               return new File(FileUtils.replaceExtension(path, DEFAULT_SUFFIX));
+       }
+
+       
+       private void createExportDialog() {
+               if (dialog == null) {
+                       dialog = new FileDialog(window.getShell(), SWT.SAVE | SWT.SHEET);
+                       dialog.setText("Export Transparent PNG");
+                       dialog.setFilterExtensions(new String[]{"*.png"});
+                       dialog.setFilterNames(new String[]{"PNG Images"});
+               }
+               
+               dialog.setFileName(getFileName());
+               
+               String dir = getDirectory();
+               if (dir != null) {
+                       // Unfortunately this is buggy on SWT/GTK and
+                       // the filter path isin't always set :'-(
+                       dialog.setFilterPath(dir);
+               }
+       }
+       
+       private String getFileName() {
+               File file = window.getContext().getFile();
+               return FileUtils.replaceExtension(file.getName(), DEFAULT_SUFFIX);
+       }
+       
+       
+       private String getDirectory() {
+               if (directory == null) {
+                       File folder = window.getContext().getFolder();
+                       directory = (folder != null) ? 
+                                       directory = folder.getAbsolutePath() : null;
+               }
+               
+               return directory;
+       }
+       
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/actions/ExportViewAction.java b/Annotation/src/ie/dcu/apps/ist/actions/ExportViewAction.java
new file mode 100644 (file)
index 0000000..a6ca7b5
--- /dev/null
@@ -0,0 +1,162 @@
+package ie.dcu.apps.ist.actions;
+
+
+import ie.dcu.apps.ist.views.SegmentationView;
+import ie.dcu.segment.SegmentationContext;
+import ie.dcu.segment.painters.SegmentationPainter;
+import ie.dcu.swt.*;
+import ie.dcu.util.FileUtils;
+
+import java.io.*;
+import java.util.logging.Level;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.*;
+
+
+/**
+ * Export current view as image.
+ * 
+ * @author Kevin McGuinness
+ */
+public class ExportViewAction extends AppAction {
+       
+       private static final String DEFAULT_SUFFIX = ".png";
+       
+       private FileDialog dialog;
+       private String directory;
+       
+       public ExportViewAction(ActionManager m) {
+               super(m);
+       }
+
+       @Override 
+       public void run() { 
+               if (window.hasContext()) {
+                       File file = getFile();
+                       if (file != null) {
+                               directory = file.getParent();
+                               export(file);
+                       }
+               }               
+       }
+
+
+       private void export(File file) {
+               Image im = paintContext();
+               
+               try {
+                       SwtUtils.saveImage(im, file);
+                       status("View successfully exported as %s", file.getName());
+                       
+               } catch (IOException e) {
+               
+                       handleError(file, e);
+                       
+               } finally {
+                       
+                       im.dispose();
+               }
+       }
+
+       
+       private void handleError(File file, IOException e) {
+               // Log
+               log(Level.WARNING, "Error exporting view as image", e);
+               
+               // Show error dialog
+               error("Error exporting view as image %s: %s", 
+                               file.getName(), e.getLocalizedMessage()
+               );
+               
+               // Set status message
+               status(Error, "Error exporting view as image %s", file.getName());
+       }
+
+       
+       private File getFile() {
+               createExportDialog();
+               
+               String path = dialog.open();
+               if (path != null) {
+                       return checkFile(path);
+               }
+               
+               return null;
+       }
+       
+       
+       private File checkFile(String path) {
+               File file = new File(path);
+
+               if (SwtUtils.getImageFormat(file) != -1) {
+                       return file;
+               } 
+               
+               // Unknown file extension, so assume jpg
+               return new File(FileUtils.replaceExtension(path, DEFAULT_SUFFIX));
+       }
+
+       
+       private void createExportDialog() {
+               if (dialog == null) {
+                       dialog = new FileDialog(window.getShell(), SWT.SAVE | SWT.SHEET);
+                       dialog.setText(property("ExportViewAction.dialog.text"));
+                       dialog.setFilterExtensions(getFilters());
+                       dialog.setFilterNames(getFilterNames());
+               }
+               
+               dialog.setFileName(getFileName());
+               
+               String dir = getDirectory();
+               if (dir != null) {
+                       // Unfortunately this is buggy on SWT/GTK and
+                       // the filter path isin't always set :'-(
+                       dialog.setFilterPath(dir);
+               }
+       }
+       
+       private String getFileName() {
+               File file = window.getContext().getFile();
+               return FileUtils.replaceExtension(file.getName(), DEFAULT_SUFFIX);
+       }
+       
+       
+       private String getDirectory() {
+               if (directory == null) {
+                       File folder = window.getContext().getFolder();
+                       directory = (folder != null) ? 
+                                       directory = folder.getAbsolutePath() : null;
+               }
+               
+               return directory;
+       }
+       
+       
+       
+       private String[] getFilters() {
+               return new String[] { property("ExportViewAction.dialog.filter.exts") };
+       }
+       
+       
+       private String[] getFilterNames() {
+               return new String[] { property("ExportViewAction.dialog.filter.text") };
+       }
+       
+       
+       private Image paintContext() {
+               SegmentationView view = window.getView();
+               SegmentationContext ctx = window.getContext();
+               SegmentationPainter painter = view.getPainter();
+               ObservableImage im = createCompatibleImage(ctx);
+               painter.paint(ctx, im);
+               return im.getImage();
+       }
+       
+       
+       private ObservableImage createCompatibleImage(SegmentationContext ctx) {
+               Image im = new Image(Display.getCurrent(), ctx.getBounds());
+               return new ObservableImage(im);
+       }
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/actions/HelpAction.java b/Annotation/src/ie/dcu/apps/ist/actions/HelpAction.java
new file mode 100644 (file)
index 0000000..6905dd6
--- /dev/null
@@ -0,0 +1,126 @@
+package ie.dcu.apps.ist.actions;
+
+import ie.dcu.swt.layout.LayoutFactory;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.browser.Browser;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+
+/**
+ * Show a help dialog.
+ * 
+ * @author Kevin McGuinness
+ */
+public class HelpAction extends AppAction {
+       
+       private HelpBox dialog;
+       
+       
+       public HelpAction(ActionManager m) {
+               super(m);
+       }
+
+       
+       @Override 
+       public void run() { 
+               if (dialog == null) {
+                       dialog = new HelpBox();
+               }
+               
+               if (dialog.available()) {
+                       dialog.open();
+               } else {
+                       info("Help browser unavailable on this system");
+               }
+       }
+       
+       
+       /**
+        * Help dialog box, just wraps a browser.
+        */
+       private class HelpBox {
+               private Shell shell;
+               private Composite content;
+               private Browser browser;
+               
+               
+               public HelpBox() {
+                       createShell();
+                       createContent();
+               }
+
+
+               private void createShell() {
+                       shell = new Shell(window.getShell(), SWT.SHELL_TRIM);
+                       
+                       // Prevent the shell from disposing on close
+                       shell.addShellListener(new ShellAdapter() {
+                               public void shellClosed(ShellEvent evt) {
+                                       evt.doit = false;
+                                       close();
+                               }
+                       });
+                       
+                       // Use a fill layout
+                       shell.setLayout(new GridLayout());
+                       
+                       // Set size and title
+                       shell.setSize(640, 480);
+                       shell.setText("Help");
+               }
+
+
+               private void createContent() {
+                       // Create content pane
+                       content = new Composite(shell, SWT.BORDER);
+                       content.setLayout(new FillLayout());
+                       content.setLayoutData(LayoutFactory.createGridData());
+                       
+                       // Add browser widget
+                       try {
+                               browser = new Browser(content, SWT.NONE);
+                       } catch (SWTError e) {
+                               
+                               // Log warning and return
+                               log.warning("Browser unavailable: " + e.getMessage());
+                               browser = null;
+                               return;
+                       }
+                       
+                       // Go to help home page
+                       home();
+               }
+
+
+               public void home() {
+                       String urlString = string("helpURL");
+                       if (urlString != null) {
+                               go(urlString);
+                       } else {
+                               browser.setText("Help file is unavailable");
+                       }
+               }
+               
+               
+               public void go(String url) {
+                       browser.setUrl(url);
+               }
+                               
+               
+               public boolean available() {
+                       return browser != null;
+               }
+               
+               
+               public void open() {
+                       shell.setVisible(true);
+               }
+               
+               
+               public void close() {
+                       shell.setVisible(false);
+               }
+       }       
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/actions/HoverAction.java b/Annotation/src/ie/dcu/apps/ist/actions/HoverAction.java
new file mode 100644 (file)
index 0000000..cf933bc
--- /dev/null
@@ -0,0 +1,88 @@
+package ie.dcu.apps.ist.actions;
+
+import org.eclipse.jface.action.*;
+import org.eclipse.jface.resource.*;
+
+/**
+ * Default implementation of {@link IHoverAction}. 
+ * 
+ * @author Kevin McGuinness
+ */
+public class HoverAction extends Action implements IHoverAction {
+       private boolean armed = false;
+       
+       /**
+        * Creates a new action with no text and no image. Configure the action later
+        * using the set methods.
+        */
+       public HoverAction() {
+               super();
+       }
+
+
+       /**
+        * Creates a new action with the given text and no image.
+        * 
+        * @param text
+        *          the string used as the text for the action, or <code>null</code>
+        *          if there is no text
+        */
+       public HoverAction(String text) {
+               super(text);
+       }
+
+
+       /**
+        * Creates a new action with the given text and image.
+        * 
+        * @param text
+        *          the action's text, or <code>null</code> if there is no text
+        * @param image
+        *          the action's image, or <code>null</code> if there is no image
+        */
+       public HoverAction(String text, ImageDescriptor image) {
+               super(text, image);
+       }
+
+
+       /**
+        * Creates a new action with the given text and style.
+        * 
+        * @param text
+        *            the action's text, or <code>null</code> if there is no text.
+        * @param style
+        *            one of 
+        *            <code>AS_PUSH_BUTTON</code>,
+        *            <code>AS_CHECK_BOX</code>, 
+        *            <code>AS_DROP_DOWN_MENU</code>,
+        *            <code>AS_RADIO_BUTTON</code>, and
+        *            <code>AS_UNSPECIFIED</code>.
+        */
+       public HoverAction(String text, int style) {
+               super(text, style);
+       }
+
+
+       /**
+        * Sets the armed property to <code>true</code>.
+        */
+       public void arm() {
+               armed = true;
+       }
+
+
+       /**
+        * Sets the armed property to <code>false</code>.
+        */
+       public void disarm() {
+               armed = false;
+       }
+
+
+       /**
+        * Returns <code>true</code> if armed.
+        */
+       public boolean isArmed() {
+               return armed;
+       }
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/actions/HoverMenuManager.java b/Annotation/src/ie/dcu/apps/ist/actions/HoverMenuManager.java
new file mode 100644 (file)
index 0000000..d3b051a
--- /dev/null
@@ -0,0 +1,149 @@
+package ie.dcu.apps.ist.actions;
+
+import ie.dcu.apps.ist.widgets.ImageMenuManager;
+
+import java.net.URL;
+import java.util.*;
+
+import org.eclipse.jface.action.*;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.widgets.*;
+
+/**
+ * Menu Manager that notifies instances of IHoverAction when they are armed and
+ * disarmed.
+ * 
+ * @author Kevin McGuinness
+ */
+public class HoverMenuManager extends ImageMenuManager  {
+       
+       /**
+        * Stores items that have hover listeners added to them. 
+        */
+       private final Set<MenuItem> hoverItems = new HashSet<MenuItem>();
+       
+       
+       /**
+        * Create hover menu manager.
+        */
+       public HoverMenuManager() {
+               init();
+       }
+
+       
+       /**
+        * Create hover menu manager with id and text.
+        * 
+        * @param text
+        *          the text for the menu, or <code>null</code> if none.
+        * @param imageURL
+        *          the menu image url, or <code>null</code>.
+        */
+       public HoverMenuManager(String text, URL imageURL) {
+               super(text, imageURL);
+               init();
+       }
+
+
+  /**
+        * Create hover menu manager text.
+        * 
+        * @param text
+        *          the text for the menu, or <code>null</code> if none.
+        */
+       public HoverMenuManager(String text) {
+               super(text);
+               init();
+       }
+
+       
+       private void init() {
+               addMenuListener(menuListener);
+       }
+
+
+       private void addHoverListeners() {
+               Menu menu = getMenu();
+               for (MenuItem item : menu.getItems()) {
+                       addHoverListener(item);
+               }
+       }
+       
+
+       private void addHoverListener(MenuItem item) {
+               IHoverAction action = getHoverAction(item);
+               if (action != null) {
+                       addHoverListener(item, action);
+               }
+       }
+
+       
+       private void addHoverListener(MenuItem item, IHoverAction action) {
+               if (!hoverItems.contains(item)) {
+                       item.addArmListener(new HoverListener(action));
+                       hoverItems.add(item);
+               }
+       }
+       
+       
+       private void disarmAll() {
+               Menu menu = getMenu();
+               for (MenuItem item : menu.getItems()) {
+                       disarm(item);
+               }
+       }
+       
+       
+       private void disarm(MenuItem item) {
+               IHoverAction action = getHoverAction(item);
+               if (action != null) {
+                       disarm(action);
+               }
+       }
+
+
+       private void disarm(IHoverAction action) {
+               if (action.isArmed()) {
+                       action.disarm();
+               }
+       }
+       
+       
+       private IHoverAction getHoverAction(MenuItem item) {
+               Object data = item.getData();
+               if (data instanceof ActionContributionItem) {
+                       IAction action = ((ActionContributionItem) data).getAction();
+                       
+                       if (action instanceof IHoverAction) {
+                               return (IHoverAction) action;
+                       }
+               }
+               return null;
+       }
+
+
+       private IMenuListener menuListener = new IMenuListener2() {
+               public void menuAboutToShow(IMenuManager manager) {
+                       addHoverListeners();
+               }
+
+               public void menuAboutToHide(IMenuManager manager) {
+                       disarmAll();
+               }               
+       };
+       
+       
+       private final class HoverListener implements ArmListener {
+               private final IHoverAction action;
+
+               public HoverListener(IHoverAction action) {
+                       this.action = action;
+               }
+
+               
+               public void widgetArmed(ArmEvent e) {
+                       disarmAll();
+                       action.arm();
+               }
+       }
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/actions/IHoverAction.java b/Annotation/src/ie/dcu/apps/ist/actions/IHoverAction.java
new file mode 100644 (file)
index 0000000..cac72be
--- /dev/null
@@ -0,0 +1,34 @@
+package ie.dcu.apps.ist.actions;
+
+import org.eclipse.jface.action.*;
+
+/**
+ * Extension of IAction that supports arming when the mouse hovers over the
+ * item. This may be useful for displaying descriptions of menu items in the
+ * status bar, for example. To use hover actions the {@link HoverMenuManager}
+ * must be used.
+ * 
+ * @author Kevin McGuinness
+ */
+public interface IHoverAction extends IAction {
+       
+       
+       /**
+        * Executed when the action is hovered/armed.
+        */
+       public void arm();
+       
+       
+       /**
+        * Executed when the action is de-hovered/disarmed.
+        */
+       public void disarm();
+       
+       
+       /**
+        * Query if the action is armed.
+        * 
+        * @return <code>true</code> if armed.
+        */
+       public boolean isArmed();
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/actions/NextAction.java b/Annotation/src/ie/dcu/apps/ist/actions/NextAction.java
new file mode 100644 (file)
index 0000000..900618b
--- /dev/null
@@ -0,0 +1,122 @@
+/**
+ * 
+ */
+package ie.dcu.apps.ist.actions;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * Jump to the next image in the directory
+ * 
+ * @author Kevin McGuinness
+ */
+public class NextAction extends AppAction {
+       // Supported file extensions
+       static final String EXTENSIONS = "jpg;jpeg;png;gif;bmp;ctx";
+       
+       private final java.io.FileFilter imageFilter;
+
+       
+       public NextAction(ActionManager m) {
+               super(m);
+               
+               // Create an image file filter
+               imageFilter = new SimpleFileFilter(EXTENSIONS);
+       }
+
+       
+       @Override 
+       public void run() {
+               if (window.hasContext()) {
+                       // Get currently opened file
+                       File file = window.getContext().getFile();
+                       
+                       // Find the one after & open it
+                       File next = findNext(file);
+                       if (next != null) {
+                               manager.get(OpenAction.class).open(next);
+                       }
+               }
+       }
+       
+       
+       private File findNext(File file) {
+               File dir = file.getParentFile();
+               
+               if (dir != null) {
+                       
+                       // List the images
+                       File[] files = dir.listFiles(imageFilter);
+                       
+                       // Need at least one
+                       if (files.length > 1) {
+                               
+                               // Search for ourself...
+                               for (int i = 0; i < files.length; i++) {
+                                       
+                                       if (files[i].equals(file)) {
+                                               
+                                               // Use next file (wrap back to first)
+                                               return files[(i+1)%files.length];
+                                       }
+                               }
+                       }
+               }
+               
+               return null;
+       }
+       
+}
+
+class SimpleFileFilter implements java.io.FileFilter {
+       
+       /**
+        * Holds the list of extensions. It is expected it will be quite
+        * short, so we use an ArrayList.
+        */
+       private final ArrayList<String> extensions;
+       
+       
+       /**
+        * Construct a simple file extension filter based on a semicolon separated
+        * list of file extensions.
+        * 
+        * @param extensions
+        *          A list of file extensions (ex. jpeg;jpg;png)
+        */
+       public SimpleFileFilter(String extensions) {
+               String[] exts = extensions.split(";");
+               this.extensions = new ArrayList<String>(exts.length);
+               
+               for (String s : exts) {
+                       if ((s = s.trim()).length() != 0) {
+                               if (s.startsWith("*")) {
+                                       s = s.substring(1);
+                               }
+                               
+                               if (!s.startsWith(".")) {
+                                       s = "." + s;
+                               }
+                               
+                               this.extensions.add(s);
+                       }
+               }
+       }
+       
+
+       public boolean accept(File pathname) {
+               if (pathname.isFile()) {
+                       String name = pathname.getName();
+                       
+                       // List of extensions should be fairly short..
+                       for (String ext : extensions) {
+                               if (name.endsWith(ext)) {
+                                       return true;
+                               }
+                       }
+               }
+               
+               return false;
+       }
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/actions/OpenAction.java b/Annotation/src/ie/dcu/apps/ist/actions/OpenAction.java
new file mode 100644 (file)
index 0000000..823f176
--- /dev/null
@@ -0,0 +1,110 @@
+package ie.dcu.apps.ist.actions;
+
+import ie.dcu.apps.ist.*;
+import ie.dcu.segment.SegmentationContext;
+
+import java.io.*;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.widgets.*;
+
+/**
+ * Open an image or segmentation context.
+ * 
+ * @author Kevin McGuinness
+ */
+public class OpenAction extends AppAction {
+
+       private FileDialog dialog;
+       
+       public OpenAction(ActionManager m) {
+               super(m);
+       }
+       
+
+       @Override
+       public void run() {
+               File file = getFile();
+               if (file != null) {
+                       open(file);
+               }
+       }
+       
+
+       public boolean open(File file) {
+               String name = file.getName();
+               try {
+                       if (SegmentationContext.isContextFile(file)) {
+                       
+                               // Load context
+                               window.setContext(SegmentationContext.load(file));
+                               status("Opened segmentation context %s successfully", name);
+                       } else {
+                       
+                               // Create context
+                               window.setContext(SegmentationContext.create(file));
+                               status("Opened image file %s successfully", name);
+                       }
+                       
+                       // Save history
+                       AppRecentFiles.getInstance().add(file);
+                       
+                       // Ok
+                       return true;
+                       
+               } catch (IOException e) {
+                       
+                       handleError(file, e);
+                       status(Warning, "Proplem opening file %s", name);
+               
+                       return false;
+               }
+       }
+
+
+       private void handleError(File file, IOException e) {
+
+               // Get appropriate message
+               String message = e.getCause() == null ? e.getLocalizedMessage() :
+                       e.getCause().getLocalizedMessage();
+               
+               // Log warning
+               log.warning(String.format(
+                               "Unable to open %s\n Problem: %s", file, message
+               ));
+
+               // Show warning dialog
+               warning("Unable to open %s:\n%s", file.getName(), message);
+       }
+
+
+       private void createOpenDialog() {
+               // Create dialog if necessary
+               if (dialog == null) {
+                       dialog = new FileDialog(window.getShell(), SWT.OPEN | SWT.SHEET);
+                       dialog.setText(property("OpenAction.dialog.text"));
+                       dialog.setFilterExtensions(getFilters());
+                       dialog.setFilterNames(getFilterNames());
+               }
+       }
+       
+       private String[] getFilters() {
+               return new String[] { property("OpenAction.dialog.filter.exts") };
+       }
+       
+       private String[] getFilterNames() {
+               return new String[] { property("OpenAction.dialog.filter.text") };
+       }
+       
+       
+       private File getFile() {
+               createOpenDialog();
+               
+               String path = dialog.open();
+               if (path != null) {
+                       return new File(path);
+               }
+               
+               return null;
+       }
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/actions/OpenExperimentAction.java b/Annotation/src/ie/dcu/apps/ist/actions/OpenExperimentAction.java
new file mode 100644 (file)
index 0000000..2e27dd4
--- /dev/null
@@ -0,0 +1,98 @@
+/**
+ * 
+ */
+package ie.dcu.apps.ist.actions;
+
+import ie.dcu.apps.ist.exp.*;
+
+import java.io.*;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.widgets.*;
+
+/**
+ * Open an experiment file and switch to experiment mode.
+ * 
+ * @author Kevin McGuinness
+ */
+public class OpenExperimentAction extends AppAction {
+       
+       private FileDialog dialog;
+       
+
+       public OpenExperimentAction(ActionManager m) {
+               super(m);
+       }
+
+       
+       @Override
+       public void run() {
+               File file = getFile();
+               if (file != null) {
+                       open(file);
+               }
+       }
+       
+       
+       private void open(File file) {
+               try {
+                       Experiment ex = ExperimentFactory.getInstance().load(file);
+                       window.setExperiment(ex);
+                       
+               } catch (IOException ex) {
+                       handleError(file, ex);
+               } catch (FormatException ex) {
+                       handleError(file, ex);
+               }
+       }
+       
+       
+       private void handleError(File file, Exception ex) {
+               // Get appropriate message
+               String mesg = ex.getMessage();
+               
+               // Log warning
+               log.warning(String.format(
+                               "Unable to open experiment file %s\n Problem: %s", file, mesg
+               ));
+
+               // Show warning dialog
+               warning("Unable to open experiment file %s:\n%s", file.getName(), mesg);
+       }
+
+
+       private File getFile() {
+               createOpenDialog();
+               
+               String path = dialog.open();
+               if (path != null) {
+                       return new File(path);
+               }
+               
+               return null;
+       }
+       
+       
+       private void createOpenDialog() {
+               // Create dialog if necessary
+               if (dialog == null) {
+                       dialog = new FileDialog(window.getShell(), SWT.OPEN | SWT.SHEET);
+                       dialog.setText(property("OpenExperimentAction.dialog.text"));
+                       dialog.setFilterExtensions(getFilters());
+                       dialog.setFilterNames(getFilterNames());
+               }
+       }
+       
+       private String[] getFilters() {
+               return new String[] { 
+                               property("OpenExperimentAction.dialog.filter.exts") 
+               };
+       }
+       
+       private String[] getFilterNames() {
+               return new String[] { 
+                               property("OpenExperimentAction.dialog.filter.text") 
+               };
+       }
+       
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/actions/OpenRecentAction.java b/Annotation/src/ie/dcu/apps/ist/actions/OpenRecentAction.java
new file mode 100644 (file)
index 0000000..299117e
--- /dev/null
@@ -0,0 +1,25 @@
+package ie.dcu.apps.ist.actions;
+
+import java.io.*;
+
+/**
+ * Action to open a recent file.
+ * 
+ * @author Kevin McGuinness
+ */
+public class OpenRecentAction extends AppAction {
+       private final File file;
+
+       public OpenRecentAction(ActionManager m, File file) {
+               super(m);
+               this.file = file;
+               setText(file.getName());
+               String path = file.getAbsolutePath();
+               setToolTipText(path);
+               setDescription(String.format("Open file %s", path));
+       }
+       
+       public void run() {
+               manager.get(OpenAction.class).open(file);
+       }
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/actions/PreferencesAction.java b/Annotation/src/ie/dcu/apps/ist/actions/PreferencesAction.java
new file mode 100644 (file)
index 0000000..1ccfc38
--- /dev/null
@@ -0,0 +1,24 @@
+package ie.dcu.apps.ist.actions;
+
+import ie.dcu.apps.ist.dialogs.*;
+
+/**
+ * Show preferences dialog box.
+ * 
+ * @author Kevin McGuinness
+ */
+public class PreferencesAction extends AppAction {
+       private PrefsDialog dialog;
+       
+       public PreferencesAction(ActionManager m) {
+               super(m);
+       }
+
+       
+       public void run() { 
+               if (dialog == null) {
+                       dialog = new PrefsDialog(window);
+               }
+               dialog.open();
+       }
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/actions/PreviousAction.java b/Annotation/src/ie/dcu/apps/ist/actions/PreviousAction.java
new file mode 100644 (file)
index 0000000..4bfb907
--- /dev/null
@@ -0,0 +1,67 @@
+/**
+ * 
+ */
+package ie.dcu.apps.ist.actions;
+
+import java.io.*;
+
+/**
+ * Jump to previous file in current directory.
+ * 
+ * @author Kevin McGuinness
+ */
+public class PreviousAction extends AppAction {
+       private final java.io.FileFilter imageFilter;
+
+
+       public PreviousAction(ActionManager m) {
+               super(m);
+               
+               // Create an image file filter
+               imageFilter = new SimpleFileFilter(NextAction.EXTENSIONS);
+       }
+       
+       
+       @Override 
+       public void run() {
+               if (window.hasContext()) {
+                       // Get currently opened file
+                       File file = window.getContext().getFile();
+                       
+                       // Find the one before & open it
+                       File next = findPrevious(file);
+                       if (next != null) {
+                               manager.get(OpenAction.class).open(next);
+                       }
+               }
+       }
+       
+
+       
+       private File findPrevious(File file) {
+               File dir = file.getParentFile();
+               
+               if (dir != null) {
+                       
+                       // List the images
+                       File[] files = dir.listFiles(imageFilter);
+                       
+                       // Need at least one
+                       if (files.length > 1) {
+                               
+                               // Search for ourself...
+                               for (int i = 0; i < files.length; i++) {
+                                       
+                                       if (files[i].equals(file)) {
+                                               
+                                               // Use previous file (wrap back to last)
+                                               return files[(i > 0) ? i - 1 : files.length - 1];
+                                       }
+                               }
+                       }
+               }
+               
+               return null;
+       }
+
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/actions/PrintAction.java b/Annotation/src/ie/dcu/apps/ist/actions/PrintAction.java
new file mode 100644 (file)
index 0000000..3645631
--- /dev/null
@@ -0,0 +1,107 @@
+package ie.dcu.apps.ist.actions;
+
+
+import ie.dcu.apps.ist.views.SegmentationView;
+import ie.dcu.segment.SegmentationContext;
+import ie.dcu.segment.painters.SegmentationPainter;
+import ie.dcu.swt.ObservableImage;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.printing.*;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * Send current view to printer.
+ * 
+ * @author Kevin McGuinness
+ */
+public class PrintAction extends AppAction {
+       
+       private static final String JOB_NAME = "Interactive Segmentation Tool";
+       private PrintDialog dialog;
+       
+       public PrintAction(ActionManager m) {
+               super(m);
+       }
+
+       @Override 
+       public void run() { 
+               if (window.hasContext()) {
+                       status("Printing...");
+                       PrinterData data = getPrintData();
+                       if (data != null) {
+                               print(data);
+                               status("Printing complete");
+                       } else {
+                               status(null);
+                       }
+               }
+       }
+       
+       
+       private PrinterData getPrintData() {
+               createPrintDialog();
+               return dialog.open();
+       }
+
+
+       private void print(PrinterData data) {
+               Printer printer = new Printer(data);
+               try {
+                       print(printer);
+                       
+               } finally {
+                       printer.dispose();
+               }
+       }
+
+
+       private void print(Printer printer) {
+               if (printer.startJob(JOB_NAME)) {
+                       if (printer.startPage()) {
+                               GC gc = new GC(printer);
+                               try {
+                                       paint(gc, printer);
+                               } finally {
+                                       gc.dispose();
+                               }
+                               printer.endPage();
+                       }
+                       printer.endJob();
+               }
+       }
+
+       
+       private void paint(GC gc, Printer printer) {
+               Image im = paintContext();
+               try {
+                       gc.drawImage(im, 30, 30);
+               } finally {
+                       im.dispose();
+               }
+       }
+       
+
+       private void createPrintDialog() {
+               if (dialog == null) {
+                       dialog = new PrintDialog(window.getShell(), SWT.SHEET);
+               }
+       }
+       
+       
+       private Image paintContext() {
+               SegmentationView view = window.getView();
+               SegmentationContext ctx = window.getContext();
+               SegmentationPainter painter = view.getPainter();
+               ObservableImage im = createCompatibleImage(ctx);
+               painter.paint(ctx, im);
+               return im.getImage();
+       }
+       
+       
+       private ObservableImage createCompatibleImage(SegmentationContext ctx) {
+               Image im = new Image(Display.getCurrent(), ctx.getBounds());
+               return new ObservableImage(im);
+       }
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/actions/RedoAction.java b/Annotation/src/ie/dcu/apps/ist/actions/RedoAction.java
new file mode 100644 (file)
index 0000000..4e84880
--- /dev/null
@@ -0,0 +1,23 @@
+package ie.dcu.apps.ist.actions;
+
+import ie.dcu.apps.ist.views.SegmentationView;
+
+
+/**
+ * Redo last annotation action.
+ * 
+ * @author Kevin McGuinness
+ */
+public class RedoAction extends AppAction {
+       public RedoAction(ActionManager m) {
+               super(m);
+       }
+
+       @Override 
+       public void run() {
+               SegmentationView view = window.getView();
+               if (view.canRedo()) {
+                       view.redo();
+               }
+       }
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/actions/SaveAction.java b/Annotation/src/ie/dcu/apps/ist/actions/SaveAction.java
new file mode 100644 (file)
index 0000000..e652d28
--- /dev/null
@@ -0,0 +1,120 @@
+package ie.dcu.apps.ist.actions;
+
+import java.io.*;
+import java.util.logging.*;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.widgets.*;
+
+/**
+ * Save segmentation context.
+ * 
+ * @author Kevin McGuinness
+ */
+public class SaveAction extends AppAction {
+       
+       private FileDialog dialog;
+
+       public SaveAction(ActionManager m) {
+               super(m);
+       }
+
+       
+       @Override
+       public void run() {
+               
+               if (window.hasContext()) {
+                       
+                       File file;
+                       if (window.hasContextFile()) {
+                               file = window.getContextFile();
+                       } else {
+                               file = getFile();
+                       }
+                       
+                       if (file != null) {
+                               save(file);
+                       }
+               }
+       }
+       
+
+       private void createSaveDialog() {
+               if (dialog == null) {
+                       dialog = new FileDialog(window.getShell(), SWT.SAVE | SWT.SHEET);
+                       dialog.setText(property("SaveAction.dialog.text"));
+                       dialog.setFilterExtensions(getFilters());
+                       dialog.setFilterNames(getFilterNames());
+                       
+                       String dir = getDirectory();
+                       if (dir != null) {
+                               dialog.setFilterPath(dir);
+                       }
+               }
+               
+               dialog.setFileName(getFileName());
+       }
+       
+       
+       private String getDirectory() {
+               File folder = window.getContext().getFolder();
+               if (folder != null) {
+                       return folder.getAbsolutePath();
+               }
+               
+               return null;
+       }
+       
+       
+       private String getFileName() {
+               return window.getContext().getDefaultFilename();
+       }
+       
+       
+       private String[] getFilters() {
+               return new String[] { property("SaveAction.dialog.filter.exts") };
+       }
+       
+       
+       private String[] getFilterNames() {
+               return new String[] { property("SaveAction.dialog.filter.text") };
+       }
+
+       
+       private File getFile() {
+               createSaveDialog();
+               
+               String path = dialog.open();
+               if (path != null) {
+                       return new File(path);
+               }
+               
+               return null;
+       }
+       
+       
+       private void save(File file) {
+               try {
+                       window.getContext().save(file);
+                       window.updateWindowTitle();
+                       status("Saved context %s successfully", file.getName());
+               } catch (IOException e) {
+                       handleError(file, e);
+               }
+       }
+
+
+       private void handleError(File file, IOException e) {
+               
+               // Log
+               log(Level.SEVERE, "Error saving file", e);
+               
+               // Show error dialog
+               error("Error saving segmentation context %s: %s", 
+                               file.getName(), e.getLocalizedMessage()
+               );
+               
+               // Set status message
+               status(Error, "Error saving segmentation context %s", file.getName());
+       }
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/actions/SaveAsAction.java b/Annotation/src/ie/dcu/apps/ist/actions/SaveAsAction.java
new file mode 100644 (file)
index 0000000..7db1c26
--- /dev/null
@@ -0,0 +1,112 @@
+package ie.dcu.apps.ist.actions;
+
+import java.io.*;
+import java.util.logging.*;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.widgets.*;
+
+/**
+ * Save segmentation context as.
+ * 
+ * @author Kevin McGuinness
+ */
+public class SaveAsAction extends AppAction {
+       
+       private FileDialog dialog;
+
+       public SaveAsAction(ActionManager m) {
+               super(m);
+       }
+       
+       @Override
+       public void run() {             
+               if (window.hasContext()) {
+                       File file = getFile();
+                       if (file != null) {
+                               save(file);
+                       }
+               }
+       }
+       
+       
+       private void createSaveDialog() {
+               if (dialog == null) {
+                       dialog = new FileDialog(window.getShell(), SWT.SAVE | SWT.SHEET);
+                       dialog.setText(property("SaveAction.dialog.text"));
+                       dialog.setFilterExtensions(getFilters());
+                       dialog.setFilterNames(getFilterNames());
+                       
+                       String dir = getDirectory();
+                       if (dir != null) {
+                               dialog.setFilterPath(dir);
+                       }
+               }
+               
+               dialog.setFileName(getFileName());
+       }
+       
+       
+       private String getDirectory() {
+               File folder = window.getContext().getFolder();
+               if (folder != null) {
+                       return folder.getAbsolutePath();
+               }
+               
+               return null;
+       }
+       
+       
+       
+       private String getFileName() {
+               return window.getContext().getDefaultFilename();
+       }
+       
+       
+       private String[] getFilters() {
+               return new String[] { property("SaveAction.dialog.filter.exts") };
+       }
+       
+       
+       private String[] getFilterNames() {
+               return new String[] { property("SaveAction.dialog.filter.text") };
+       }
+       
+       
+       private File getFile() {
+               createSaveDialog();
+               
+               String path = dialog.open();
+               if (path != null) {
+                       return new File(path);
+               }
+               
+               return null;
+       }
+       
+       
+       private void save(File file) {
+               try {
+                       window.getContext().save(file);
+                       window.updateWindowTitle();
+                       status("Saved context %s successfully", file.getName());
+               } catch (IOException e) {
+                       handleError(file, e);
+               }
+       }
+       
+       
+       private void handleError(File file, IOException e) {
+               
+               // Log
+               log(Level.SEVERE, "Error saving file", e);
+               
+               // Show error dialog
+               error("Error saving segmentation context %s: %s", 
+                               file.getName(), e.getLocalizedMessage()
+               );
+               
+               // Set status message
+               status(Error, "Error saving segmentation context %s", file.getName());
+       }
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/actions/SelectSegmenterAction.java b/Annotation/src/ie/dcu/apps/ist/actions/SelectSegmenterAction.java
new file mode 100644 (file)
index 0000000..485ec8a
--- /dev/null
@@ -0,0 +1,60 @@
+package ie.dcu.apps.ist.actions;
+
+import ie.dcu.apps.ist.SegmenterRegistry;
+import ie.dcu.apps.ist.views.SegmentationView;
+import ie.dcu.segment.Segmenter;
+
+/**
+ * Segmenter radio buttons.
+ * 
+ * @author Kevin McGuinness
+ */
+public class SelectSegmenterAction extends AppAction {
+       private final Segmenter segmenter;
+
+       public SelectSegmenterAction(ActionManager m, SegmenterRegistry r, Segmenter s) {
+               super(m, AS_RADIO_BUTTON);
+               this.segmenter = s;
+               setText(s.getName());
+               setToolTipText(s.getDescription());
+               
+               if (!s.isAvailable()) {
+                       super.setEnabled(false);
+                       setChecked(false);
+                       
+                       String naText = string("NA");
+                       setToolTipText(naText);
+                       setDescription(naText);
+               } else {
+                       setChecked(r.isDefault(s));
+               }
+       }
+       
+       public void setEnabled(boolean enabled) {
+               // Disallow enabling unavailable segmentation algorithms
+               if (!enabled || (segmenter.isAvailable() && enabled)) {
+                       super.setEnabled(enabled);
+               }
+       }
+       
+       
+       public Segmenter getSegmenter() {
+               return segmenter;
+       }
+
+       
+       @Override
+       public String id() {
+               return segmenter.getClass().getName();
+       }
+
+
+       @Override
+       public void run() {
+               if (isChecked()) {
+                       SegmentationView view = window.getView();
+                       view.setSegmenter(segmenter);           
+               }
+       }
+       
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/actions/UndoAction.java b/Annotation/src/ie/dcu/apps/ist/actions/UndoAction.java
new file mode 100644 (file)
index 0000000..d5c67f2
--- /dev/null
@@ -0,0 +1,22 @@
+package ie.dcu.apps.ist.actions;
+
+import ie.dcu.apps.ist.views.SegmentationView;
+
+/**
+ * Undo last annotation.
+ *  
+ * @author Kevin McGuinness
+ */
+public class UndoAction extends AppAction {
+       public UndoAction(ActionManager m) {
+               super(m);
+       }
+
+       @Override 
+       public void run() { 
+               SegmentationView view = window.getView();
+               if (view.canUndo()) {
+                       view.undo();
+               }
+       }
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/controllers/AnnotationTool.java b/Annotation/src/ie/dcu/apps/ist/controllers/AnnotationTool.java
new file mode 100644 (file)
index 0000000..eb89bb0
--- /dev/null
@@ -0,0 +1,314 @@
+package ie.dcu.apps.ist.controllers;
+
+
+
+import ie.dcu.segment.annotate.*;
+import ie.dcu.swt.*;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.widgets.Canvas;
+
+public class AnnotationTool extends MouseMotionAdapter {
+       private final AnnotationManager manager;        
+       private ImageControl view;
+       private Canvas canvas;
+       
+       private Annotation current;
+       private AnnotationType type;
+       private int lineWidth;
+       private Point last;
+       private boolean invert;
+
+       
+       public AnnotationTool(AnnotationManager manager) {
+               this (manager, null);
+       }
+       
+       /**
+        * 
+        * @param manager
+        * @param view
+        */
+       public AnnotationTool(AnnotationManager manager, ImageControl view) {
+               assert (manager != null);
+               
+               this.manager = manager;
+               this.current = null;
+               this.lineWidth = 1;
+               this.type = AnnotationType.Foreground;
+               
+               attach(view);
+       }
+
+
+       /**
+        * 
+        * @param view
+        */
+       public void attach(ImageControl view) {
+               detach();
+       
+               if (view != null) {
+                       this.view = view;
+                       canvas = view.getCanvas();
+                       canvas.addMouseListener(this);
+                       canvas.addMouseMoveListener(this);
+               }
+       }
+               
+
+
+       public void detach() {
+               if (view != null) {
+                       canvas.removeMouseListener(this);
+                       canvas.removeMouseMoveListener(this);
+                       view = null;
+                       canvas = null;
+                       current = null;
+               }
+       }
+       
+       
+       /**
+        * Returns the image control associated with the annotation tool.
+        */
+       public ImageControl getView() {
+               return view;
+       }
+       
+               
+       /**
+        * @return the line width
+        */
+       public int getLineWidth() {
+               return lineWidth;
+       }
+
+
+       /**
+        * @param width the line width to set
+        */
+       public void setLineWidth(int width) {
+               assert (width > 0);
+               this.lineWidth = width;
+       }
+
+
+       /**
+        * @return the annotation type
+        */
+       public AnnotationType getType() {
+               return type;
+       }
+
+       
+       /**
+        * @param type the annotation type to set
+        */
+       public void setType(AnnotationType type) {
+               assert (type != null);
+               this.type = type;
+       }
+       
+
+
+       public void begin(Point pt) {           
+                       
+               // Create a new annotation
+               current = new Annotation(getTypeForUse(), lineWidth, view.canvasToImage(pt));
+               
+               // Give immediate visual feedback
+               feedback(pt);
+               
+               // Set last
+               last = pt;
+       }
+       
+       
+       public void append(Point pt) {
+                       
+               // Update the annotation
+               current.add(view.canvasToImage(pt));
+               
+               // Give immediate visual feedback
+               feedback(last, pt);
+               
+               // Set last
+               last = pt;
+       }
+       
+       
+       public void commit(Point pt) {
+               // Clip points to image bounds
+               clip(last, pt);
+               
+               // Add point to annotation
+               current.add(view.canvasToImage(pt));
+                       
+               // Add annotation to annotation manager
+               manager.add(current);
+               
+               // Give immediate visual feedback
+               feedback(last, pt);
+                       
+               // Mark current annotation as null
+               current = null;
+       }
+       
+       
+       public void cancel() {
+               
+               // Repaint dirty area
+               view.repaint(current.getBounds());
+               
+               // Discard annotation
+               current = null;
+       }
+       
+       
+       
+       @Override
+       public void mouseDown(MouseEvent e) {
+               if (view == null || !view.isEnabled()) {
+                       current = null;
+                       return;
+               }
+                       
+               ObservableImage image = view.getImage();
+               if (image != null) {
+                       
+                       if (e.button == 1 || e.button == 3) {
+                               
+                               Point pt = new Point(e.x, e.y);
+                               
+                               if (view.imageContains(pt)) {
+                               
+                                       // Check for right mouse button or ctrl modifier
+                                       
+                                       if (e.button == 3 || (e.stateMask & SWT.CTRL) != 0) {
+                                               // Invert type
+                                               invert = true;
+                                       } else {
+                                               invert = false;
+                                       }
+                                       
+                                       if (current != null) {
+                                               // Cancel last action
+                                               cancel();
+                                       }
+                                       
+                                       begin(pt);
+                               }
+                       }
+               }
+               
+               return;
+       }
+
+       
+       @Override
+       public void mouseMove(MouseEvent e) {
+               if (view == null || !view.isEnabled()) {
+                       current = null;
+                       return;
+               }
+               
+               if (current != null) {
+                       Point pt = new Point(e.x, e.y);
+                       
+                       if (view.imageContains(pt)) {
+                               // Normal case: append
+                               append(pt);
+                               
+                       } else {
+                               // Line drawn outside image
+                               
+                               if (view.getImage() != null) {
+                                       
+                                       commit(pt);
+                               
+                               } else {
+                                       // No image: cancel
+                                       cancel();
+                               }
+                       } 
+               }
+               
+       }
+
+
+       @Override
+       public void mouseUp(MouseEvent e) {
+               if (view == null || !view.isEnabled()) {
+                       current = null;
+                       return;
+               }
+               
+               if (current != null) {
+                       Point pt = new Point(e.x, e.y);
+                       
+                       if (view.imageContains(pt)) {
+                               
+                               // Normal case: commit
+                               commit(pt);
+                       } else {
+                               
+                         // Line drawn outside image
+                               if (view.getImage() != null) {
+                                       
+                                       commit(pt);
+                               } else {
+                                       
+                                       // No image
+                                       cancel();
+                               }
+                       }
+               }
+       }
+
+
+       private void clip(Point p, Point q) {
+               SwtUtils.clip(view.getCanvasImageBounds(), p, q);
+       }
+       
+
+       private GC createFeedbackGC() {
+               GC gc = new GC(canvas);
+               gc.setAntialias(SWT.ON);
+               gc.setLineCap(SWT.CAP_ROUND);
+               gc.setLineJoin(SWT.JOIN_ROUND);
+               gc.setLineWidth((int) Math.floor(lineWidth * view.getZoom()));
+               gc.setForeground(getTypeForUse().getColor());
+               return gc;
+       }
+       
+       
+       private void feedback(Point p1) {
+               feedback(p1, new Point(p1.x+1, p1.y));
+       }
+       
+       
+       private void feedback(Point p1, Point p2) {
+               GC gc = createFeedbackGC();
+               gc.setClipping(getClip(p1, p2));
+               gc.drawLine(p1.x, p1.y, p2.x, p2.y);
+               gc.dispose();
+       }
+       
+       
+       private Rectangle getClip(Point p1, Point p2) {
+               int x1 = Math.min(p1.x, p2.x) - lineWidth;
+               int x2 = Math.max(p1.x, p2.x) + lineWidth;
+               int y1 = Math.min(p1.y, p2.y) - lineWidth;
+               int y2 = Math.max(p1.y, p2.y) + lineWidth;
+               Rectangle r = new Rectangle(x1, y1, x2 - x1, y2 - y1);
+               return  r.intersection(view.getCanvasImageBounds());
+       }
+
+       
+       private AnnotationType getTypeForUse() {
+               return (invert) ? type.invert() : type;
+       }
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/controllers/MouseMotionAdapter.java b/Annotation/src/ie/dcu/apps/ist/controllers/MouseMotionAdapter.java
new file mode 100644 (file)
index 0000000..70a08e4
--- /dev/null
@@ -0,0 +1,26 @@
+package ie.dcu.apps.ist.controllers;
+
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.widgets.*;
+
+public class MouseMotionAdapter extends MouseAdapter implements MouseMoveListener {
+
+       public MouseMotionAdapter() {
+       }
+
+
+       public MouseMotionAdapter(Control control) {
+               add(control);
+       }
+
+
+       public void add(Control control) {
+               control.addMouseListener(this);
+               control.addMouseMoveListener(this);
+       }
+
+
+       public void mouseMove(MouseEvent e) {   
+       }
+
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/dialogs/ExportDialog.java b/Annotation/src/ie/dcu/apps/ist/dialogs/ExportDialog.java
new file mode 100644 (file)
index 0000000..6807637
--- /dev/null
@@ -0,0 +1,368 @@
+package ie.dcu.apps.ist.dialogs;
+
+import ie.dcu.apps.ist.export.imagemap.AreaShape;
+import ie.dcu.apps.ist.export.imagemap.RolloverEffect;
+import ie.dcu.swt.SwtUtils;
+import ie.dcu.swt.layout.LayoutFactory;
+
+import java.io.File;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Dialog;
+import org.eclipse.swt.widgets.DirectoryDialog;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.MessageBox;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+public class ExportDialog extends Dialog {
+
+       public class Result {
+               public final File folder;
+               public final String html;
+               public final String image;
+               public final String link;
+               public final String description;
+               public final AreaShape shape;
+               public final RolloverEffect effect;
+               public final boolean open;
+               
+               Result() {
+                       folder = new File(folderText.getText().trim());
+                       html = htmlText.getText().trim();
+                       image = imageText.getText().trim();
+                       link = linkText.getText().trim();
+                       description = descriptionText.getText();
+                       shape = getShape();
+                       effect = getEffect();
+                       open = openButton.getSelection();
+               }
+       };
+       
+       // Result
+       private Result result;
+       
+       // Top level components
+       private Shell shell;
+       private Composite content;
+       private Composite widgets;
+       private Composite buttons;
+       
+       // Widgets
+       private Text folderText;
+       private Button browseButton;
+       private Text htmlText;
+       private Text imageText;
+       private Text linkText;
+       private Button effectCheck;
+       private Combo effectCombo;
+       private Button[] shapeRadios;
+       private Text descriptionText;
+       private Button openButton;
+       
+       // Dialog buttons
+       private Button cancelButton;
+       private Button exportButton;
+       
+       // Effects
+       private final String[] ROLLOVER_EFFECTS = {
+               "Outline Object", "Darken Background", "Highlight Object"
+       };
+       
+       // Shapes
+       private final String[] SHAPES = {
+               "Polygon", "Rectangle", "Circle"
+       };
+       
+       // Default title
+       private static final String TITLE = "Export HTML Image Map";
+
+       public ExportDialog(Shell shell) {
+               super(shell);
+               setText(TITLE);
+       }
+
+       public ExportDialog(Shell shell, int style) {
+               super(shell, style);
+               setText(TITLE);
+       }
+       
+       public Result open() {
+               Shell parent = getParent();
+               shell = new Shell(parent, SWT.DIALOG_TRIM | 
+                       SWT.APPLICATION_MODAL | SWT.SHEET);
+               shell.setText(getText());
+               shell.setLayout(new FillLayout());
+               
+               createUI();
+               
+               shell.pack();
+               
+               SwtUtils.center(parent, shell);
+               
+               shell.open();
+               Display display = parent.getDisplay();
+               while (!shell.isDisposed()) {
+                       if (!display.readAndDispatch()) display.sleep();
+               }
+
+               return result;
+       }
+
+       private void createUI() {
+               // Overall layout
+               content = new Composite(shell, 0);
+               content.setLayout(LayoutFactory.createGridLayout(0, 0, 1, false));
+               widgets = new Composite(content, 0);
+               widgets.setLayout(LayoutFactory.createGridLayout(10, 5, 3, false));
+               widgets.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+               hline(content);
+               buttons = new Composite(content, 0);
+               buttons.setLayout(LayoutFactory.createGridLayout(10, 5, 3, false));
+               buttons.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+               
+               // Form content
+               label(widgets, "Export folder:");
+               folderText = text(widgets, "");
+               browseButton = button(widgets, "Browse...");
+               label(widgets, "HTML file name:");
+               htmlText = text(widgets, "imagemap.html");
+               spacer(widgets);
+               label(widgets, "Image file name:");
+               imageText = text(widgets, "image.png");
+               spacer(widgets);
+               hline(widgets);
+               label(widgets, "Export shape:");
+               shapeRadios = radios(widgets, SHAPES);
+               // TODO: Enable when available
+               shapeRadios[2].setEnabled(false);
+               spacer(widgets);
+               label(widgets, "Object link:");
+               linkText = text(widgets, "http://");
+               spacer(widgets);
+               label(widgets, "Object description:");
+               descriptionText = text(widgets, "");
+               spacer(widgets);
+               effectCheck = checkbox(widgets, "Rollover effect:", true, 1);
+               effectCombo = combo(widgets, ROLLOVER_EFFECTS);
+               spacer(widgets);
+               hline(widgets);
+               openButton = checkbox(widgets, 
+                               "Open image map in browser after export completes", true, 3);
+               
+               // Button bar
+               expander(buttons);
+               cancelButton = new Button(buttons, SWT.PUSH);
+               cancelButton.setLayoutData(layout4());
+               cancelButton.setText("Cancel");
+               exportButton = new Button(buttons, SWT.PUSH);
+               exportButton.setLayoutData(layout4());
+               exportButton.setText("Export");
+               
+               // Set the default button
+               shell.setDefaultButton(exportButton);
+               
+               // Add listeners
+               addListeners();
+       }
+       
+       private void addListeners() {
+               
+               browseButton.addListener(SWT.Selection, new Listener() {
+                       public void handleEvent(Event e) {
+                               String dir = getDirectory();
+                               if (dir != null) {
+                                       folderText.setText(dir);
+                               }
+                       }
+               });
+               
+               cancelButton.addListener(SWT.Selection, new Listener() {
+                       public void handleEvent(Event e) {
+                               result = null;
+                               shell.dispose();
+                       }
+               });
+               
+               exportButton.addListener(SWT.Selection, new Listener() {
+                       public void handleEvent(Event e) {
+                               if (validate()) {
+                                       result = new Result();
+                                       shell.dispose();
+                               }
+                       }
+               });
+               
+               effectCheck.addListener(SWT.Selection, new Listener() {
+                       public void handleEvent(Event e) {
+                               effectCombo.setEnabled(effectCheck.getSelection());
+                       }
+               });
+       }
+       
+       private boolean validate() {
+               
+               File folder = new File(folderText.getText());
+               if (!folder.isDirectory()) {
+                       validationError("The export folder must be specified");
+                       folderText.setFocus();
+                       return false;
+               }
+               
+               String htmlFile = htmlText.getText().trim();
+               if (htmlFile.equals("")) {
+                       validationError("The HTML file name cannot be empty");
+                       htmlText.setFocus();
+                       return false;
+               }
+               
+               String imageFile = imageText.getText().trim();
+               if (imageFile.equals("")) {
+                       validationError("The image file name cannot be empty");
+                       imageText.setFocus();
+                       return false;
+               }
+               
+               return true;
+       }
+       
+       private void validationError(String message) {
+               MessageBox box = new MessageBox(shell, SWT.OK | SWT.ICON_INFORMATION);
+               box.setMessage(message);
+               box.setText("Invalid Input");
+               box.open();
+       }
+
+       private AreaShape getShape() {
+               for (Button bt : shapeRadios) {
+                       if (bt.getSelection()) {
+                               return AreaShape.valueOf(bt.getText());
+                       }
+               }
+               return null;
+       }
+       
+       private RolloverEffect getEffect() {
+               RolloverEffect effect = null;
+               if (effectCheck.getSelection()) {
+                       String text = effectCombo.getText();
+                       if (text.equals("Outline Object")) {
+                               effect = RolloverEffect.outlineObject();
+                       } else if (text.equals("Darken Background")) {
+                               effect = RolloverEffect.darkenBackground();
+                       } else if (text.equals("Highlight Object")) {
+                               effect = RolloverEffect.brightenForeground();
+                       }
+               } 
+               return effect;
+       }
+       
+       private String getDirectory() {
+               DirectoryDialog dialog = new DirectoryDialog(shell);
+               return dialog.open();
+       }
+
+       private Button[] radios(Composite parent, String ... items) {
+               Composite c = new Composite(parent, SWT.NONE);
+               c.setLayout(LayoutFactory.createGridLayout(5, 10, items.length, false));
+               c.setLayoutData(layout2());
+               
+               Button[] bts = new Button[items.length];
+               for (int i = 0; i < bts.length; i++) {
+                       bts[i] = new Button(c, SWT.RADIO);
+                       bts[i].setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false));
+                       bts[i].setText(items[i]);
+                       bts[i].setSelection(i == 0);
+               }
+               
+               return bts;
+       }
+       
+       private Label hline(Composite parent) {
+               Label label = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL);
+               GridData data = new GridData(SWT.FILL, SWT.CENTER, false, false);
+               data.horizontalSpan = 3;
+               data.heightHint = 10;
+               label.setLayoutData(data);
+               return label;
+       }
+       
+       private Label spacer(Composite parent) {
+               Label label = new Label(parent, SWT.NONE);
+               label.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
+               return label;
+       }
+       
+       private Label expander(Composite parent) {
+               Label label = new Label(parent, SWT.NONE);
+               label.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+               return label;
+       }
+       
+       private Combo combo(Composite parent, String ... items) {
+               Combo combo = new Combo(parent, SWT.READ_ONLY);
+               combo.setItems(items);
+               combo.setLayoutData(layout2());
+               if (items.length > 0) {
+                       combo.select(0);
+               }
+               return combo;
+       }
+       
+       private Button checkbox(Composite parent, String text, 
+                       boolean checked, int span) {
+               
+               Button bt = new Button(parent, SWT.CHECK);
+               bt.setText(text);
+               bt.setSelection(checked);
+               GridData data = layout1();
+               data.horizontalSpan = span;
+               bt.setLayoutData(data);
+               return bt;
+       }
+       
+       private Label label(Composite parent, String text) {
+               Label label = new Label(parent, SWT.NONE);
+               label.setText(text);
+               label.setLayoutData(layout1());
+               return label;
+       }
+       
+       private Text text(Composite parent, String value) {
+               Text text = new Text(parent, SWT.BORDER | SWT.SINGLE);
+               text.setText(value);
+               text.setLayoutData(layout2());
+               return text;
+       }
+       
+       private Button button(Composite parent, String text) {
+               Button bt = new Button(parent, SWT.PUSH);
+               bt.setText(text);
+               bt.setLayoutData(layout3());
+               return bt;
+       }
+       
+       private GridData layout1() {
+               return new GridData(SWT.LEFT, SWT.CENTER, false, false);
+       }
+       
+       private GridData layout2() {
+               return new GridData(SWT.FILL, SWT.CENTER, true, false);
+       }
+       
+       private GridData layout3() {
+               return new GridData(SWT.RIGHT, SWT.CENTER, false, false);
+       }
+       
+       private GridData layout4() {
+               return new GridData(SWT.RIGHT, SWT.BOTTOM, false, false);
+       }
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/dialogs/PrefsDialog.java b/Annotation/src/ie/dcu/apps/ist/dialogs/PrefsDialog.java
new file mode 100644 (file)
index 0000000..9ea4eeb
--- /dev/null
@@ -0,0 +1,435 @@
+package ie.dcu.apps.ist.dialogs;
+
+import static ie.dcu.segment.annotate.AnnotationType.*;
+import ie.dcu.apps.ist.*;
+import ie.dcu.apps.ist.AppPrefs.Keys;
+import ie.dcu.apps.ist.widgets.ColorSelector;
+import ie.dcu.swt.SwtUtils;
+import ie.dcu.swt.layout.LayoutFactory;
+
+import java.util.*;
+
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+
+public class PrefsDialog {
+       private static final String APPLICATION = "application";
+       private static final String STATUS      = "status";
+       private static final String VIEW        = "view";
+       private static final String TITLE       = "title";
+       private static final String GENERAL     = "general";
+       private static final String CLOSE       = "close";
+       private static final String RESET       = "reset";
+       private static final String TEXT        = "text";
+       private static final String ICON        = "icon";
+       private static final String TTIP        = "ttip";
+       private static final String EXPERIMENT  = "experiment";
+       
+       private final AppWindow window;
+       private final AppPrefs prefs;
+       private final Shell shell;
+       private final Composite content;
+       private final TabFolder folder;
+       private final Composite buttonBar;
+       private final Composite generalTab;
+       private final Button resetButton;
+       private final Button closeButton;
+       private final HashMap<String, Object> controls;
+       
+       private transient GridData gd;
+       
+
+       public PrefsDialog(AppWindow window) {
+               this.window = window;
+               this.prefs = window.getPrefs();
+               this.shell = createShell();
+               this.content = createContent();
+               this.folder = createTabFolder();
+               this.buttonBar = createButtonBar();
+               this.generalTab = createTab(GENERAL);
+               this.resetButton = createResetButton();
+               this.closeButton = createCloseButton();
+               this.controls = new HashMap<String, Object>();
+               
+               createControls();
+               loadPreferences();
+               
+               SwtUtils.center(window.getShell(), shell);
+       }
+       
+
+       private void createControls() {
+               // Initialize general tab
+               createBanner(generalTab, APPLICATION);
+               
+               createLabel(generalTab, Keys.CONFIRM_EXIT);
+               createCheckBox(generalTab, Keys.CONFIRM_EXIT);
+               
+               createBanner(generalTab, STATUS);
+               
+               createLabel(generalTab, Keys.ENABLE_FEEDBACK);
+               createCheckBox(generalTab, Keys.ENABLE_FEEDBACK);
+               
+               createBanner(generalTab, VIEW);
+               
+               createLabel(generalTab, Keys.FOREGROUND_COLOR);
+               createColorSelector(generalTab, Keys.FOREGROUND_COLOR);
+               
+               createLabel(generalTab, Keys.BACKGROUND_COLOR);
+               createColorSelector(generalTab, Keys.BACKGROUND_COLOR);
+               
+               createBanner(generalTab, EXPERIMENT);
+               
+               createLabel(generalTab, Keys.EXPERIMENT_EMBEDDED);
+               createCheckBox(generalTab, Keys.EXPERIMENT_EMBEDDED);
+       }
+
+       
+       private void loadPreferences() {
+               
+               // Load confirm exit
+               loadBool(Keys.CONFIRM_EXIT, true);
+               
+               // Load enable feedback 
+               loadBool(Keys.ENABLE_FEEDBACK, true);
+               
+               // Load foreground color 
+               loadColor(Keys.FOREGROUND_COLOR, DEFAULT_FOREGROUND);
+               
+               // Load background color 
+               loadColor(Keys.BACKGROUND_COLOR, DEFAULT_BACKGROUND);
+               
+               // Load experiment embedded
+               loadBool(Keys.EXPERIMENT_EMBEDDED, false);
+       }
+       
+
+       private Shell createShell() {
+               Shell s = new Shell(window.getShell(), SWT.SHELL_TRIM | SWT.SHEET);
+               
+               // Add listener
+               s.addListener(SWT.Close, adapter);
+               
+               // Use a fill layout
+               s.setLayout(new FillLayout());
+               
+               // Set size and title
+               s.setSize(420, 450);
+               s.setText(property(TITLE, "Preferences"));
+               
+               return s;
+       }
+       
+       
+       private Composite createContent() {
+               
+               // Create content pane with grid layout
+               Composite c = new Composite(shell, 0);
+               c.setLayout(new GridLayout());
+               return c;
+       }
+       
+       
+       private TabFolder createTabFolder() {
+               // Create folder
+               TabFolder f = new TabFolder(content, SWT.TOP);
+               
+               // Layout folder
+               f.setLayoutData(LayoutFactory.createGridData());
+               
+               return f;
+       }
+       
+       
+       private Composite createButtonBar() {
+               // Create bar
+               Composite bar = new Composite(content, SWT.NONE);
+               
+               // Layout bar
+               bar.setLayout(LayoutFactory.createGridLayout(0, 0, 2, true));
+               bar.setLayoutData(new GridData(SWT.FILL, SWT.BOTTOM, true, false));
+               
+               return bar;
+       }
+       
+       
+       private Composite createTab(String name) {
+               // Create item
+               TabItem item = new TabItem(folder, SWT.NONE);
+               item.setText(property(name, "tab", name));
+               
+               // Create control
+               Composite control = new Composite(folder, SWT.NONE);
+               control.setLayout(LayoutFactory.createGridLayout(10, 5, 2, false));
+               
+               // Set control
+               item.setControl(control);
+               
+               // Return control (item can be ignored)
+               return control;
+       }
+       
+       
+       private Button createResetButton() {
+               // Create button
+               Button bt = createButton(buttonBar, RESET, SWT.PUSH);
+               
+               // Layout button
+               gd = new GridData(SWT.LEFT, SWT.BOTTOM, true, false);
+               gd.minimumWidth = 85;
+               bt.setLayoutData(gd);
+               
+               // Done
+               return bt;
+       }
+       
+       
+       private Button createCloseButton() {
+               // Create button
+               Button bt = createButton(buttonBar, CLOSE, SWT.PUSH);
+               
+               // Layout button
+               gd = new GridData(SWT.RIGHT, SWT.BOTTOM, true, false);
+               gd.minimumWidth = 85;
+               bt.setLayoutData(gd);
+               
+               // Done
+               return bt;
+       }
+       
+       
+       private Button createCheckBox(Composite tab, String key) {
+               Button bt = new Button(tab, SWT.CHECK);
+               
+               // Layout button
+               gd = new GridData(SWT.RIGHT, SWT.CENTER, false, false);
+               gd.horizontalIndent = 5;
+               bt.setLayoutData(gd);
+               
+               // Add listener
+               bt.addListener(SWT.Selection, adapter);
+               bt.setData(key);
+               
+               // Put into controls
+               controls.put(key, bt);
+               
+               // Done
+               return bt;
+       }
+       
+       
+       private ColorSelector createColorSelector(Composite tab, String key) {
+               ColorSelector cs = new ColorSelector(tab);
+               
+               // Layout button
+               gd = new GridData(SWT.RIGHT, SWT.CENTER, false, false);
+               gd.horizontalIndent = 10;
+               gd.minimumWidth = 80;
+               cs.setLayoutData(gd);
+               
+               // Add listener
+               cs.addListener(SWT.Selection, adapter);
+               cs.setData(key);
+               
+               // Put into controls
+               controls.put(key, cs);
+               
+               // Done
+               return cs;
+       }
+
+
+       private Label createBanner(Composite tab, String key) {
+               // Create label
+               Label lb = new Label(tab, SWT.NONE);
+               lb.setText(property(key, key));
+               lb.setFont(JFaceResources.getBannerFont());
+               
+               // Layout label
+               gd = new GridData(SWT.LEFT, SWT.CENTER, true, false, 2, 1);
+               gd.verticalIndent = 5;
+               lb.setLayoutData(gd);
+               
+               return lb;
+       }
+       
+       
+       private Label createLabel(Composite tab, String key) {
+               // Create label
+               Label lb = new Label(tab, SWT.NONE);
+               lb.setText(property(key, TEXT, key));
+               
+               // Layout label
+               gd = new GridData(SWT.LEFT, SWT.CENTER, true, false);
+               gd.horizontalIndent = 5;
+               lb.setLayoutData(gd);
+               
+               return lb;
+       }
+       
+       
+       private Button createButton(Composite parent, String key, int style) {
+               Button bt = new Button(parent, style);
+               
+               // Configure button
+               configure(bt, key);
+               
+               // Add listener
+               bt.addListener(SWT.Selection, adapter);
+               
+               // Done
+               return bt;
+       }       
+       
+       
+       protected void handleEvent(Event event) {
+               switch (event.type) {
+               case SWT.Close:
+                       handleClose(event);
+                       break;
+               case SWT.Selection:
+                       handleSelection(event);
+                       break;
+               }
+               
+       }
+       
+
+       private void handleClose(Event event) {
+               // Prevent the shell from disposing on close
+               event.doit = false;
+               close();
+       }
+       
+
+       private void handleSelection(Event event) {
+               if (event.widget == closeButton) {
+                       close();
+               } else if (event.widget == resetButton) {
+                       reset();
+               } else {
+                       Object data = event.widget.getData();
+                       if (data instanceof String) {
+                               handleSelection(event, (String) data);
+                       }
+               }
+               
+       }
+
+
+       private void handleSelection(Event event, String key) {
+               
+               if (key.equals(Keys.ENABLE_FEEDBACK)) {
+                       storeBool(key);
+               
+               } else if (key.equals(Keys.FOREGROUND_COLOR)) {
+
+                       storeColor(key);
+                       
+               } else if (key.equals(Keys.BACKGROUND_COLOR)) {
+                       
+                       storeColor(key);
+               
+               } else if (key.equals(Keys.EXPERIMENT_EMBEDDED)) {
+               
+                       storeBool(key);
+               
+               } else if (key.equals(Keys.CONFIRM_EXIT)) {
+                       
+                       storeBool(key);
+               }
+               
+       }
+       
+       
+       private void storeBool(String key) {
+               Boolean bool = control(Button.class, key).getSelection();
+               prefs.put(Boolean.class, key, bool);
+       }
+       
+
+       private void storeColor(String key) {
+               RGB color = control(ColorSelector.class, key).getColor();
+               if (color != null) {
+                       prefs.put(RGB.class, key, color);
+               }
+       }
+       
+       
+       private void loadBool(String key, boolean def) {
+               Boolean bool = prefs.get(Boolean.class, key, def);
+               control(Button.class, key).setSelection(bool);
+       }
+       
+       
+       private void loadColor(String key, RGB def) {
+               RGB color = prefs.get(RGB.class, key, def);
+               control(ColorSelector.class, key).setColor(color);
+       }
+       
+
+       public void reset() {
+               // Set defaults
+               prefs.clear();
+               
+               // Reload
+               loadPreferences();
+       }
+
+
+       public void close() {
+               shell.setVisible(false);
+       }
+       
+       
+       public void open() {
+               shell.setVisible(true);
+       }
+       
+       
+       private void configure(Button bt, String key) {
+               // Read properties
+               String text = property(key, TEXT, "");
+               String icon = property(key, ICON, null);
+               String ttip = property(key, TTIP, null);
+               
+               // Set values
+               bt.setText(text);
+               bt.setImage(image(icon));
+               bt.setToolTipText(ttip);
+               bt.setData(key);
+       }
+       
+       
+       private <T> T control(Class<T> clazz, String key) {
+               return clazz.cast(controls.get(key));
+       }
+       
+       
+       private String property(String key, String def) {
+               Properties p = window.getProperties();
+               return p.getProperty(String.format("PrefsDialog.%s", key), def);
+       }
+       
+       
+       private String property(String key, String type, String def) {
+               Properties p = window.getProperties();
+               String prop = String.format("PrefsDialog.%s.%s", key, type);
+               return p.getProperty(prop, def);
+       }
+       
+       
+       private Image image(String url) {
+               return (url != null) ? window.getIcon(url) :  null;
+       }
+       
+       
+       private final Listener adapter = new Listener() {
+               public void handleEvent(Event event) {
+                       PrefsDialog.this.handleEvent(event);
+               }               
+       };
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/event/ContextChangeListener.java b/Annotation/src/ie/dcu/apps/ist/event/ContextChangeListener.java
new file mode 100644 (file)
index 0000000..8c617a0
--- /dev/null
@@ -0,0 +1,7 @@
+package ie.dcu.apps.ist.event;
+
+import java.util.*;
+
+public interface ContextChangeListener extends EventListener {
+       public void contextChanged(ContextChangedEvent evt);
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/event/ContextChangedEvent.java b/Annotation/src/ie/dcu/apps/ist/event/ContextChangedEvent.java
new file mode 100644 (file)
index 0000000..638dad9
--- /dev/null
@@ -0,0 +1,24 @@
+package ie.dcu.apps.ist.event;
+
+
+import ie.dcu.segment.SegmentationContext;
+
+import java.util.*;
+
+
+public class ContextChangedEvent extends EventObject {
+       private static final long serialVersionUID = 1L;
+       
+       public final SegmentationContext oldContext;
+       public final SegmentationContext newContext;
+
+       public ContextChangedEvent(
+                       Object source, 
+                       SegmentationContext oldContext,
+                       SegmentationContext newContext
+       ) {
+               super(source);
+               this.oldContext = oldContext;
+               this.newContext = newContext;
+       }
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/event/StateEvent.java b/Annotation/src/ie/dcu/apps/ist/event/StateEvent.java
new file mode 100644 (file)
index 0000000..38c5bbc
--- /dev/null
@@ -0,0 +1,11 @@
+package ie.dcu.apps.ist.event;
+
+import java.util.*;
+
+public class StateEvent extends EventObject {
+       private static final long serialVersionUID = 1L;
+
+       public StateEvent(Object source) {
+               super(source);
+       }
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/event/StateListener.java b/Annotation/src/ie/dcu/apps/ist/event/StateListener.java
new file mode 100644 (file)
index 0000000..525f253
--- /dev/null
@@ -0,0 +1,13 @@
+/**
+ * 
+ */
+package ie.dcu.apps.ist.event;
+
+import java.util.*;
+
+/**
+ * @author Kevin McGuinness
+ */
+public interface StateListener extends EventListener {
+       public void stateChanged(StateEvent evt);
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/event/TickerEvent.java b/Annotation/src/ie/dcu/apps/ist/event/TickerEvent.java
new file mode 100644 (file)
index 0000000..ae6124f
--- /dev/null
@@ -0,0 +1,25 @@
+package ie.dcu.apps.ist.event;
+
+
+import ie.dcu.apps.ist.widgets.Ticker;
+
+import java.util.EventObject;
+
+public class TickerEvent extends EventObject {
+       private static final long serialVersionUID = 755693053854019177L;
+
+       private final long elapsed;
+
+       public TickerEvent(Ticker t, long elapsed) {
+               super(t);
+               this.elapsed = elapsed;
+       }
+       
+       public Ticker getTicker() {
+               return (Ticker) getSource();
+       }
+       
+       public long getElapsed() {
+               return elapsed;
+       }
+};
diff --git a/Annotation/src/ie/dcu/apps/ist/event/TickerListener.java b/Annotation/src/ie/dcu/apps/ist/event/TickerListener.java
new file mode 100644 (file)
index 0000000..26b6269
--- /dev/null
@@ -0,0 +1,7 @@
+package ie.dcu.apps.ist.event;
+
+import java.util.*;
+
+public interface TickerListener extends EventListener {
+       public void tick(TickerEvent evt);
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/event/TimeoutEvent.java b/Annotation/src/ie/dcu/apps/ist/event/TimeoutEvent.java
new file mode 100644 (file)
index 0000000..70659c3
--- /dev/null
@@ -0,0 +1,24 @@
+/**
+ * 
+ */
+package ie.dcu.apps.ist.event;
+
+
+import ie.dcu.apps.ist.widgets.SwtTimer;
+
+import java.util.EventObject;
+
+/**
+ * @author Kevin McGuinness
+ */
+public class TimeoutEvent extends EventObject {
+       private static final long serialVersionUID = 1L;
+
+       public TimeoutEvent(SwtTimer source) {
+               super(source);
+       }
+       
+       public SwtTimer getTimer() {
+               return (SwtTimer) getSource();
+       }
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/event/TimeoutListener.java b/Annotation/src/ie/dcu/apps/ist/event/TimeoutListener.java
new file mode 100644 (file)
index 0000000..c682041
--- /dev/null
@@ -0,0 +1,13 @@
+/**
+ * 
+ */
+package ie.dcu.apps.ist.event;
+
+import java.util.*;
+
+/**
+ * @author Kevin McGuinness
+ */
+public interface TimeoutListener extends EventListener {
+       public void timeoutOccured(TimeoutEvent evt);
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/exp/Experiment.java b/Annotation/src/ie/dcu/apps/ist/exp/Experiment.java
new file mode 100644 (file)
index 0000000..ef52005
--- /dev/null
@@ -0,0 +1,348 @@
+package ie.dcu.apps.ist.exp;
+
+import ie.dcu.eval.Evaluator;
+import ie.dcu.apps.ist.*;
+import ie.dcu.segment.Segmenter;
+
+import java.io.*;
+import java.util.*;
+
+public class Experiment {
+       public static final int MAX_TASKS = 2500;
+       public static final int MAX_SEGMENTERS = 50;
+       public static final int MAX_EVALUATORS = 100;
+       
+       private String name;
+       private File dir;
+       private File outputFile;
+       private int time;
+       private List<Segmenter> segmenters;
+       private List<Evaluator> evaluators;
+       private List<Task> tasks;
+       private StorageSelection saveUserMasks;
+       private File saveUserMasksDir;
+       
+       Experiment() {
+               
+       }
+       
+       
+       public String getName() {
+               return name;
+       }
+       
+       
+       public File getDirectory() {
+               return dir;
+       }
+       
+       
+       public File getOutputFile() {
+               return outputFile;
+       }
+       
+       
+       public int getTime() {
+               return time;
+       }
+       
+       
+       public StorageSelection getStorageSelection() {
+               return saveUserMasks;
+       }
+       
+       
+       public File getStorageDirectory() {
+               return saveUserMasksDir;
+       }
+       
+       
+       public List<Segmenter> getSegmenters() {
+               return Collections.unmodifiableList(segmenters);
+       }
+       
+       
+       public List<Evaluator> getEvaluators() {
+               return Collections.unmodifiableList(evaluators);
+       }
+       
+       
+       public List<Task> getTasks() {
+               return Collections.unmodifiableList(tasks);
+       }
+       
+       
+       public boolean using(Segmenter segmenter) {
+               for (Segmenter s : segmenters) {
+                       if (s.equals(segmenter)) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+       
+       
+       public void load(File file) throws IOException, FormatException {
+               InputStream in = null;
+               try {
+                       in = new FileInputStream(file);
+                       load(in);
+               } finally {
+                       if (in != null) {
+                               in.close();
+                       }
+               }
+       }
+       
+       
+       public void load(InputStream in) throws IOException, FormatException {
+               
+               // Create properties object
+               Properties props = new Properties();
+               props.load(in);
+               
+               // Load name
+               name = props.getProperty("name", "Experiment");
+               
+               // Load directory
+               dir = getDir(props, "dir");
+               
+               // Load output file
+               outputFile = getOutputFile(props);
+               
+               // Load task time
+               time = getTimeout(props, "time");
+               
+               // Get save user masks selection
+               saveUserMasks = getStorageSelection(props, "save-user-masks");
+               
+               // .. and directory
+               saveUserMasksDir = getUserMaskDir(props, "save-user-masks.dir");
+               
+               // Load segmenters
+               segmenters = new ArrayList<Segmenter>();
+               for (int i = 1; i <= MAX_SEGMENTERS; i++) {
+                       String key = "segmenters." + i;
+                       String val = props.getProperty(key);
+                       
+                       if (val == null) {
+                               break;
+                       }
+                       
+                       Segmenter segmenter = findSegmenter(val);
+                       if (segmenter != null) {
+                               segmenters.add(segmenter);
+                       } else {
+                               exception("Segmenter not found: <%s>", val);
+                       }
+               }
+               
+               // Load evaluators
+               evaluators = new ArrayList<Evaluator>();
+               for (int i = 1; i <= MAX_EVALUATORS; i++) {
+                       String key = "evaluators." + i;
+                       String val = props.getProperty(key);
+                       
+                       if (val == null) {
+                               break;
+                       }
+                       
+                       Evaluator evaluator = findEvaluator(val);
+                       if (evaluator != null) {
+                               evaluators.add(evaluator);
+                       } else {
+                               exception("Evaluator not found: <%s>", val);
+                       }
+               }
+               
+               // Load tasks
+               tasks = new ArrayList<Task>();
+               for (int i = 1; i <= MAX_TASKS; i++) {
+                       
+                       // Form keys
+                       String imkey   = String.format("task.%d.im", i);
+                       String gtkey   = String.format("task.%d.gt", i);
+                       String desckey = String.format("task.%d.description", i);
+                       
+                       // Check if we're done
+                       if (props.getProperty(imkey) == null) {
+                               break;
+                       }
+                       
+                       // Get image and ground truth file
+                       File im = getFile(props, imkey);
+                       File gt = getFile(props, gtkey);
+                       
+                       // Get description
+                       String desc = getDescription(props, desckey);
+                       
+                       // Add task
+                       tasks.add(new Task(im, gt, desc));
+               }
+       }
+       
+       
+       private static StorageSelection getStorageSelection(
+               Properties props, String key
+       ) {
+               String prop = props.getProperty(key);
+               if (prop != null) {
+                       StorageSelection selection = StorageSelection.parse(prop);
+                       if (selection != null) {
+                               return selection;
+                       }
+               }
+               return StorageSelection.None;
+       }
+       
+       
+       private File getUserMaskDir(Properties props, String key) 
+               throws FormatException {
+               
+               String fname = props.getProperty(key);
+               if (fname == null) {
+                       fname = "user";
+               }
+               
+               File file = new File(fname);
+               if (!file.isAbsolute()) {
+                       file = new File(dir, fname);
+               }
+               
+               
+               if (!file.exists()) {
+                       // Try and create it
+                       if (!file.mkdirs()) {
+                               String path = file.getAbsolutePath();
+                               exception("Couldn't create directory %s", path);
+                       } 
+               
+               }       else if (!file.isDirectory()) {
+                       String path = file.getAbsolutePath();
+                       exception("%s is not a directory", path);
+               }
+               
+               return file;
+       }
+
+
+       private static Segmenter findSegmenter(String name) {
+               return SegmenterRegistry.getInstance().find(name);
+       }
+       
+       
+       private static Evaluator findEvaluator(String name) {
+               return EvaluatorRegistry.getInstance().find(name);
+       }
+       
+       
+       private File getOutputFile(Properties props) {
+               String fname = props.getProperty("output", "output.txt");
+               File file = new File(fname);
+               if (file.isAbsolute()) {
+                       return file;
+               }
+               return new File(dir, fname);
+       }
+       
+       
+       
+       private static String getDescription(Properties props, String key) 
+               throws FormatException {
+               
+               String desc = props.getProperty(key);
+               if (desc == null) {
+                       exception("Expected description property for %s", key);
+               }
+               return desc;
+       }
+       
+       
+       private File getFile(Properties props, String key) 
+               throws FormatException {
+               
+               String fname = props.getProperty(key);
+               
+               if (fname == null) {
+                       exception("Expected file property for %s", key);
+               }
+               
+               File file = new File(fname);
+               if (file.isAbsolute()) {
+                       if (file.isFile()) {
+                               return file;
+                       }
+               }
+               
+               file = new File(dir, fname);
+               if (!file.isFile()) {
+                       exception("File not found %s", file.getAbsolutePath());
+               }
+               
+               return file;
+       }
+       
+       
+       private static File getDir(Properties props, String key) 
+               throws FormatException {
+               
+               String prop = props.getProperty(key);
+               if (prop == null) {
+                       exception("Required directory element not found: %a",key);
+               }
+               
+               File file = new File(prop);
+               if (!file.isDirectory()) {
+                       exception("%s is not a directory", prop);
+               }
+               
+               return file;
+       }
+       
+       
+       private static int getTimeout(Properties props, String key) 
+               throws FormatException {
+               
+               String prop = props.getProperty(key, "120");
+               try {
+                       return Integer.parseInt(prop);
+               } catch (NumberFormatException ex) {
+                       exception("%s is not an integer", key);
+               }
+               
+               return 0;
+       }
+       
+       
+       private static void exception(String format, Object ... args) 
+               throws FormatException 
+       {
+               throw new FormatException(String.format(format, args));
+       }
+       
+       
+       public String toString() {
+               StringBuilder sb = new StringBuilder();
+               
+               sb.append("name=<").append(name).append('>');
+               sb.append(" dir=<").append(dir.getAbsolutePath()).append('>');
+               sb.append(" output=<").append(outputFile.getAbsolutePath()).append('>');
+               sb.append(" time=<").append(time).append('>');
+               
+               // Evaluators
+               sb.append(" evaluators={ ");
+               for (Evaluator e : evaluators) {
+                       sb.append(e.getName()).append(' ');
+               }
+               sb.append('}');
+               
+               // Tasks
+               sb.append(" tasks={ ");
+               for (Task t : tasks) {
+                       sb.append(t).append(' ');
+               }
+               sb.append('}');
+               
+               return sb.toString();
+       }
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/exp/ExperimentFactory.java b/Annotation/src/ie/dcu/apps/ist/exp/ExperimentFactory.java
new file mode 100644 (file)
index 0000000..802d14a
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * 
+ */
+package ie.dcu.apps.ist.exp;
+
+import java.io.*;
+
+/**
+ * @author Kevin McGuinness
+ */
+public class ExperimentFactory {
+       private static ExperimentFactory instance;
+       
+       protected ExperimentFactory() {
+               
+       }
+       
+       public static ExperimentFactory getInstance() {
+               if (instance == null) {
+                       instance = new ExperimentFactory();
+               }
+               return instance;
+       }
+       
+       
+       public Experiment load(File file) 
+               throws IOException, FormatException {
+               
+               Experiment ex = new Experiment();
+               ex.load(file);
+               return ex;
+       }
+       
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/exp/ExperimentManager.java b/Annotation/src/ie/dcu/apps/ist/exp/ExperimentManager.java
new file mode 100644 (file)
index 0000000..b03a6f7
--- /dev/null
@@ -0,0 +1,217 @@
+package ie.dcu.apps.ist.exp;
+
+import ie.dcu.eval.Evaluator;
+import ie.dcu.segment.SegmentationMask;
+import ie.dcu.segment.SegmentationContext;
+import ie.dcu.apps.ist.AppWindow;
+import ie.dcu.apps.ist.actions.*;
+
+import java.io.*;
+import java.util.List;
+
+public class ExperimentManager {
+       
+       private final AppWindow window;
+       
+       private Experiment experiment;
+       private SegmentationContext activeContext;
+       private SegmentationMask referenceMask;
+       private ExperimentResults results;
+       private List<Task> tasks;
+       private Task activeTask;
+       private int progress;
+       private boolean aborted;
+       
+       
+       public ExperimentManager(AppWindow window) {    
+               this.window = window;
+       }
+       
+       
+       public void beginExperiment(Experiment ex) throws IOException {
+               experiment = ex;
+               tasks = experiment.getTasks();
+               activeContext = null;
+               activeTask = null;
+               progress = 0;
+               results = new ExperimentResults(experiment.getOutputFile());
+               results.beginDocument();
+               results.beginExperiment(experiment);
+       }
+       
+       
+       public void endExperiment() throws IOException {
+               results.endExperiment();
+               results.flush();
+               results.close();
+       }
+       
+       
+       public void abortExperiment() {
+               results.endExperiment();
+               results.close();
+               aborted = true;
+       }
+       
+       
+       public void beginTask() throws IOException {
+               if (isComplete()) {
+                       throw new IllegalStateException();
+               }
+               
+               // Set active task
+               activeTask = tasks.get(progress);
+               
+               // Load context into main window
+               loadContext();
+
+               // Load reference mask
+               loadReferenceMask();
+               
+               // Write task header to results
+               results.beginTask(progress, activeTask);
+       }
+       
+       
+       public void endTask() throws IOException {
+               
+               try {
+                       // Save final mask
+                       StorageSelection ss = experiment.getStorageSelection();
+                       if (ss != StorageSelection.None) {
+                               store(String.format("task-%d-final.png", progress));
+                       }
+                       
+               } finally {
+                       
+                       activeTask = null;
+                       activeContext = null;
+                       progress++;
+                       results.endTask();
+                       results.flush();
+               }
+       }
+       
+       
+       public boolean isComplete() {
+               return tasks.size() == progress || aborted;
+       }
+       
+       
+       public Experiment getExperiment() {
+               return experiment;
+       }
+       
+       
+       public String getTaskDescription() {
+               return activeTask.getDescription();
+       }
+       
+       
+       public Task getActiveTask() {
+               return activeTask;
+       }
+       
+       
+       public int getTaskCount() {
+               return tasks.size();
+       }
+       
+       
+       public int getProgress() {
+               return progress;
+       }
+       
+       
+       public SegmentationContext getActiveContext() {
+               return activeContext;
+       }
+       
+       
+       public List<Evaluator> getEvaluators() {
+               return experiment.getEvaluators();
+       }
+       
+       
+       public File getImageFile() {
+               return activeTask.getImageFile();
+       }
+       
+       
+       public SegmentationMask getCurrentMask() {
+               return activeContext.getMask();
+       }
+       
+       
+       public SegmentationMask getReferenceMask() {
+               return referenceMask;
+       }
+       
+       
+       public void evaluate(int elapsed) {
+               
+               if (!getCurrentMask().isUnknown()) {
+                       SegmentationMask im = getCurrentMask();
+                       SegmentationMask gt = getReferenceMask();
+                       
+                       results.beginEvaluation(elapsed);
+                       
+                       for (Evaluator evaluator : experiment.getEvaluators()) {
+                               // Execute evaluator
+                               evaluator.run(im, gt);
+                               
+                               // Add results
+                               addResults(evaluator);
+                       }
+                       
+                       results.endEvaluation();
+               }
+       }
+       
+       
+       public void store(int elapsed) throws IOException {
+               // Save current mask
+               if (!getCurrentMask().isUnknown()) {
+                       // Only save non empty masks
+                       StorageSelection ss = experiment.getStorageSelection();
+                       if (ss == StorageSelection.All) {
+                               store(String.format("task-%d-time-%d.png", progress, elapsed));
+                       }
+               }
+       }
+       
+       
+       private void store(String name) throws IOException {
+               SegmentationMask im = getCurrentMask();
+               File dir = experiment.getStorageDirectory();
+               File file = new File(dir, name);
+               im.save(file);
+       }
+
+
+       private void addResults(Evaluator evaluator) {
+               String[] measures = evaluator.getMeasures();
+               for (String measure : measures) {
+                       double value = evaluator.getMeasure(measure);
+                       results.addMeasure(measure, value);
+               }
+       }
+
+
+       private void loadReferenceMask() throws IOException {
+               referenceMask = new SegmentationMask(activeContext.getBounds());
+               referenceMask.load(activeTask.getMaskFile());
+       }
+
+
+       private void loadContext() throws IOException {
+               ActionManager actions = window.getActions();
+               OpenAction action = actions.get(OpenAction.class);
+       
+               if (!action.open(getImageFile())) {
+                       throw new IOException("Unable to load image file");
+               }
+               
+               activeContext = window.getContext();
+       }
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/exp/ExperimentResults.java b/Annotation/src/ie/dcu/apps/ist/exp/ExperimentResults.java
new file mode 100644 (file)
index 0000000..2f54026
--- /dev/null
@@ -0,0 +1,109 @@
+package ie.dcu.apps.ist.exp;
+
+import java.io.*;
+
+public class ExperimentResults {
+       private static final String XML_HEADER =
+               "<?xml version=\"1.0\" encoding=\"UTF-8\"?>%n%n";
+       
+       private static final String BEGIN_EXPERIMENT_TAG = 
+               "<experiment name=\"%s\" time=\"%d\" dir=\"%s\">%n";
+       
+       private static final String BEGIN_TASK_TAG = 
+               "  <task id=\"%d\" image=\"%s\" gt=\"%s\">%n";
+       
+       private static final String BEGIN_EVALUATION_TAG = 
+               "    <evaluation time=\"%d\">%n";
+       
+       private static final String MEASURE_TAG = 
+               "      <measure name=\"%s\" value=\"%.5f\" />%n";
+       
+       private static final String END_EVALUATION_TAG = 
+               "    </evaluation>%n";
+       
+       private static final String END_TASK_TAG = 
+               "  </task>%n";
+       
+       private static final String END_EXPERIMENT_TAG = 
+               "</experiment>%n";
+       
+       
+       private final PrintStream out;
+       
+       
+       
+       ExperimentResults(File file) throws FileNotFoundException {
+               this(new FileOutputStream(file));
+       }
+       
+       
+       ExperimentResults(OutputStream out)  {
+               this.out = new PrintStream(new BufferedOutputStream(out));
+       }
+       
+       
+       public void beginDocument() {
+               write(XML_HEADER);
+       }
+       
+       
+       public void beginExperiment(Experiment ex) {
+               String dir = ex.getDirectory().getAbsolutePath();
+               write(BEGIN_EXPERIMENT_TAG, ex.getName(), ex.getTime(), dir);
+       }
+       
+       
+       public void beginTask(int idx, Task task) {
+               String im = task.getImageFile().getName();
+               String gt = task.getMaskFile().getName();
+               write(BEGIN_TASK_TAG, idx, im, gt);
+       }
+       
+       
+       public void beginEvaluation(int time) {
+               write(BEGIN_EVALUATION_TAG, time);
+       }
+       
+       
+       public void endEvaluation() {
+               write(END_EVALUATION_TAG);
+       }
+       
+       
+       public void addMeasure(String name, double value) {
+               write(MEASURE_TAG, name, value);
+       }
+       
+       
+       public void endTask() {
+               write(END_TASK_TAG);
+       }
+       
+       
+       public void endExperiment() {
+               write(END_EXPERIMENT_TAG);
+       }
+       
+       
+       public void endDocument() throws IOException {
+               flush();
+       }
+       
+       
+       public void flush() throws IOException {
+               out.flush();
+               if (out.checkError()) {
+                       throw new IOException();
+               }
+       }
+       
+       
+       public void close() {
+               out.close();
+       }
+       
+       
+       private void write(String format, Object ... args) {
+               out.printf(format, args);
+       }
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/exp/FormatException.java b/Annotation/src/ie/dcu/apps/ist/exp/FormatException.java
new file mode 100644 (file)
index 0000000..8553f0d
--- /dev/null
@@ -0,0 +1,48 @@
+/**
+ * 
+ */
+package ie.dcu.apps.ist.exp;
+
+/**
+ * @author Kevin McGuinness
+ */
+public class FormatException extends Exception {
+
+       /**
+        * 
+        */
+       private static final long serialVersionUID = 1L;
+
+
+       /**
+        * 
+        */
+       public FormatException() {
+       }
+
+
+       /**
+        * @param message
+        */
+       public FormatException(String message) {
+               super(message);
+       }
+
+
+       /**
+        * @param cause
+        */
+       public FormatException(Throwable cause) {
+               super(cause);
+       }
+
+
+       /**
+        * @param message
+        * @param cause
+        */
+       public FormatException(String message, Throwable cause) {
+               super(message, cause);
+       }
+
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/exp/StorageSelection.java b/Annotation/src/ie/dcu/apps/ist/exp/StorageSelection.java
new file mode 100644 (file)
index 0000000..aeae41f
--- /dev/null
@@ -0,0 +1,22 @@
+package ie.dcu.apps.ist.exp;
+
+/**
+ * Selection of what points in time to output the masks that
+ * the user has obtained so far in their interactions.
+ * 
+ * @author Kevin McGuinness
+ */
+public enum StorageSelection {
+       All,
+       None,
+       Final;
+       
+       public static StorageSelection parse(String s) {
+               for (StorageSelection ss : values()) {
+                       if (ss.toString().equalsIgnoreCase(s)) {
+                               return ss;
+                       }
+               }
+               return null;
+       }
+};
diff --git a/Annotation/src/ie/dcu/apps/ist/exp/Task.java b/Annotation/src/ie/dcu/apps/ist/exp/Task.java
new file mode 100644 (file)
index 0000000..754d4ed
--- /dev/null
@@ -0,0 +1,39 @@
+package ie.dcu.apps.ist.exp;
+
+import java.io.*;
+
+public class Task {
+
+       private final File imageFile;
+       private final File maskFile;
+       private final String description;
+
+
+       Task(File imFile, File gtFile, String desc) {
+               imageFile = imFile;
+               maskFile = gtFile;
+               description = desc;
+       }
+
+
+       public File getImageFile() {
+               return imageFile;
+       }
+
+
+       public File getMaskFile() {
+               return maskFile;
+       }
+
+
+       public String getDescription() {
+               return description;
+       }
+       
+       
+       public String toString() {
+               String im = imageFile.getAbsolutePath();
+               String gt = maskFile.getAbsolutePath();
+               return String.format("[ im=<%s> gt=<%s> desc=<%s> ]", im, gt, description);
+       }
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/export/imagemap/AreaShape.java b/Annotation/src/ie/dcu/apps/ist/export/imagemap/AreaShape.java
new file mode 100644 (file)
index 0000000..11fc339
--- /dev/null
@@ -0,0 +1,30 @@
+/**
+ * 
+ */
+package ie.dcu.apps.ist.export.imagemap;
+
+/**
+ * The shape of the area tag for a HTML image map. 
+ * 
+ * @see <a href="http://www.w3.org/TR/html401/sgml/dtd.html#Shape"/>HTML 4 DTD</a>
+ * 
+ * @author Kevin McGuinness
+ */
+public enum AreaShape {
+       Polygon("poly"),
+       Rectangle("rect"),
+       Circle("circle");
+       
+       private String text;
+       
+       private AreaShape(String text) {
+               this.text = text;
+       }
+       
+       /**
+        * Returns the HTML shape attribute value.
+        */
+       public String toString() {
+               return text;
+       }
+}
\ No newline at end of file
diff --git a/Annotation/src/ie/dcu/apps/ist/export/imagemap/ExportException.java b/Annotation/src/ie/dcu/apps/ist/export/imagemap/ExportException.java
new file mode 100644 (file)
index 0000000..51bf4c5
--- /dev/null
@@ -0,0 +1,25 @@
+package ie.dcu.apps.ist.export.imagemap;
+
+/**
+ * Exception thrown when there is a problem producing the export.
+ * 
+ * @author Kevin McGuinness
+ */
+public class ExportException extends Exception {
+       private static final long serialVersionUID = 1L;
+
+       public ExportException() {
+       }
+
+       public ExportException(String message) {
+               super(message);
+       }
+
+       public ExportException(Throwable cause) {
+               super(cause);
+       }
+
+       public ExportException(String message, Throwable cause) {
+               super(message, cause);
+       }
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/export/imagemap/Exporter.java b/Annotation/src/ie/dcu/apps/ist/export/imagemap/Exporter.java
new file mode 100644 (file)
index 0000000..09fafa1
--- /dev/null
@@ -0,0 +1,189 @@
+package ie.dcu.apps.ist.export.imagemap;
+
+import ie.dcu.image.ContourTracer;
+import ie.dcu.segment.SegmentationMask;
+import ie.dcu.util.FileUtils;
+
+import java.awt.Polygon;
+import java.awt.image.*;
+import java.io.*;
+import java.util.*;
+
+import javax.imageio.ImageIO;
+
+/**
+ * Exports HTML image maps from a segmentation mask and an image.
+ * 
+ * @author Kevin McGuinness
+ */
+public class Exporter {
+       private final SegmentationMask mask;
+       private final BufferedImage image;
+       
+       private RolloverEffect effect;
+       private String htmlFile = "imagemap.html";
+       private String imageFile = "image.png";
+       private String imageName = "image";
+       private String objectDescription = "";
+       private String objectLink = "";
+       private String title = "";
+       private AreaShape exportShape = AreaShape.Polygon;
+       
+       public Exporter(BufferedImage image, SegmentationMask mask) {
+               this.image = image;
+               this.mask = mask;
+       }
+       
+       public RolloverEffect getEffect() {
+               return effect;
+       }
+
+       public void setEffect(RolloverEffect effect) {
+               this.effect = effect;
+       }
+
+       public String getHtmlFile() {
+               return htmlFile;
+       }
+
+       public void setHtmlFile(String htmlFile) {
+               this.htmlFile = htmlFile;
+       }
+
+       public String getImageFile() {
+               return imageFile;
+       }
+
+       public void setImageFile(String imageFile) {
+               this.imageFile = imageFile;
+       }
+
+       public String getImageName() {
+               return imageName;
+       }
+
+       public void setImageName(String imageName) {
+               this.imageName = imageName;
+       }
+
+       public String getTitle() {
+               return title;
+       }
+
+       public void setTitle(String title) {
+               this.title = title;
+       }
+       
+       public String getObjectDescription() {
+               return objectDescription;
+       }
+
+       public void setObjectDescription(String description) {
+               this.objectDescription = description;
+       }
+
+       public String getObjectLink() {
+               return objectLink;
+       }
+
+       public void setObjectLink(String link) {
+               this.objectLink = link;
+       }
+
+       public AreaShape getExportShape() {
+               return exportShape;
+       }
+
+       public void setExportShape(AreaShape shape) {
+               this.exportShape = shape;
+       }
+
+       public void export(File folder) throws IOException, ExportException {
+               ContourTracer tracer = new ContourTracer(mask, SegmentationMask.FOREGROUND);
+               List<Polygon> trace = tracer.trace();
+               
+               if (trace.size() == 0) {
+                       throw new ExportException("No objects found");
+               }
+               
+               List<String> preloads = getPreloads(trace);
+               
+               // Write image
+               ImageIO.write(image, "png", new File(folder, imageFile));
+               
+               if (effect != null) {
+                       int i = 1;
+                       
+                       // Generate effect images
+                       for (Polygon object : trace) {
+                               RenderedImage im = effect.createEffect(image, object);
+                               File output = new File(folder, preloads.get(i++));
+                               ImageIO.write(im, "png", output);
+                       }
+               }
+               
+               // Create image map
+               ImageMap map = new ImageMap();
+               map.setImageHref(imageFile);
+               map.setImageName(imageName);
+               
+               // Add javascript preloads
+               for (String str : preloads) {
+                       map.addPreload(str);
+               }
+               
+               // Add areas
+               int idx = 1;
+               for (Polygon polygon : trace) {
+                       MapArea area = new MapArea();
+                       switch (exportShape) {
+                       case Polygon:
+                               area.setPolygon(polygon);
+                               break;
+                       case Rectangle:
+                               area.setRect(polygon.getBounds());
+                               break;
+                       case Circle:
+                               // TODO: Implement circle!
+                               
+                       default:
+                               area.setPolygon(polygon);
+                               break;
+                       }
+                       
+                       area.setAlt(objectDescription);
+                       area.setHref(objectLink);
+                       
+                       if (effect != null) {
+                               
+                               
+                               area.addAttr("onmouseover", 
+                                       String.format("rollover(document.%s, image%s)", 
+                                                       imageName, idx++));
+                               area.addAttr("onmouseout", 
+                                               String.format("rollover(document.%s, image0)", imageName));
+                               area.addAttr("title",getTitle());
+                       }
+                       
+                       map.addArea(area);
+               }
+               
+               map.exportToFile(new File(folder, htmlFile));
+       }
+       
+       private List<String> getPreloads(List<Polygon> trace) {
+               List<String> preloads = new ArrayList<String>();
+               preloads.add(imageFile);
+               
+               if (effect != null) {
+                       
+                       String basename = FileUtils.removeExtension(imageFile);
+                       for (int i = 0; i < trace.size(); i++) {
+                               String filename = String.format("%s-%d.png", basename, i);
+                               preloads.add(filename);
+                       }
+               }
+               
+               return preloads;
+       }
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/export/imagemap/HtmlTag.java b/Annotation/src/ie/dcu/apps/ist/export/imagemap/HtmlTag.java
new file mode 100644 (file)
index 0000000..7b0943e
--- /dev/null
@@ -0,0 +1,80 @@
+package ie.dcu.apps.ist.export.imagemap;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Class used to generate HTML tags.
+ * 
+ * @author Kevin McGuinness
+ */
+class HtmlTag {
+       final String name;
+       final Map<String, String> attrs;
+
+       HtmlTag(String name) {
+               this.name = name;
+               this.attrs = new HashMap<String, String>();
+       }
+       
+       HtmlTag attr(String name, String value) {
+               attrs.put(name, escape(value));
+               return this;
+       }
+       
+       private static String escape(String value) {
+               return value.replaceAll("\"", "\\\\\"");
+       }
+
+       static void indent(StringBuffer sb, int indent) {
+               for (int i = 0; i < indent; i++) {
+                       sb.append(' ');
+               }
+       }
+       
+       void open(StringBuffer sb, int indent) {
+               open(sb, indent, false);
+       }
+       
+       void open(StringBuffer sb, int indent, boolean empty) {
+               
+               // Indent 
+               indent(sb, indent);
+               
+               // Write start of tag
+               sb.append('<').append(name);
+               
+               // Write attributes
+               boolean first = true;
+               for (Map.Entry<String, String> entry : attrs.entrySet()) {
+                       
+                       if (!first) {
+                               sb.append('\n');
+                               indent(sb, indent + name.length() + 1);
+                       }
+                       
+                       sb.append(' ');
+                       sb.append(entry.getKey());
+                       sb.append('=');
+                       sb.append('"');
+                       sb.append(entry.getValue());
+                       sb.append('"');
+                       
+                       first = false;
+               }
+               
+               if (empty) {
+                       sb.append('/');
+               }
+               sb.append('>').append('\n');
+       }
+       
+       void close(StringBuffer sb, int indent) {
+               indent(sb, indent);
+               sb.append('<');
+               sb.append('/');
+               sb.append(name);
+               sb.append('>');
+               sb.append('\n');
+       }
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/export/imagemap/ImageMap.java b/Annotation/src/ie/dcu/apps/ist/export/imagemap/ImageMap.java
new file mode 100644 (file)
index 0000000..4125ccf
--- /dev/null
@@ -0,0 +1,184 @@
+/**
+ * 
+ */
+package ie.dcu.apps.ist.export.imagemap;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Exports HTML image maps
+ * 
+ * @author Kevin McGuinness
+ */
+public class ImageMap {
+       private static final String TEMPLATE_FILE = "template.html";
+       
+       private String pageTitle;
+       private String imageName;
+       private String imageHref;
+       private String imageAlt;
+       private String mapName;
+       private final List<MapArea> areas;
+       private final List<String> preloads;
+       
+       public ImageMap() {
+               // set defaults :
+               this.pageTitle = "Image Map";
+               this.imageName = "image";
+               this.imageHref = "";
+               this.imageAlt = "";
+               this.mapName = "imagemap";
+               this.areas = new LinkedList<MapArea>();
+               this.preloads = new LinkedList<String>();
+       }
+
+       public String getPageTitle() {
+               return pageTitle;
+       }
+
+       public void setPageTitle(String pageTitle) {
+               assert (pageTitle != null);
+               this.pageTitle = pageTitle;
+       }
+
+       public String getImageName() {
+               return imageName;
+       }
+
+       public void setImageName(String imageName) {
+               this.imageName = imageName;
+       }
+
+       public String getImageHref() {
+               return imageHref;
+       }
+
+       public void setImageHref(String imageHref) {
+               assert (imageHref != null);
+               this.imageHref = imageHref;
+       }
+
+       public String getImageAlt() {
+               return imageAlt;
+       }
+
+       public void setImageAlt(String imageAlt) {
+               assert (imageAlt != null);
+               this.imageAlt = imageAlt;
+       }
+
+       public String getMapName() {
+               return mapName;
+       }
+
+       public void setMapName(String mapName) {
+               assert (mapName != null);
+               this.mapName = mapName;
+       }
+
+       public void addArea(MapArea area) {
+               areas.add(area);
+       }
+       
+       public List<MapArea> areas() {
+               return areas;
+       }
+       
+       public void addPreload(String preload) {
+               this.preloads.add(preload);
+       }
+       
+       public List<String> preloads() {
+               return preloads;
+       }
+
+       public String export() {
+               String template = loadTemplate();
+               
+               // Create preloads buffer
+               StringBuffer preloads = new StringBuffer();
+               int idx = 0;
+               for (String s : preloads()) {
+                       HtmlTag.indent(preloads, 8);
+                       preloads.append("var image").append(idx);
+                       preloads.append(" = new Image()\n");
+                       HtmlTag.indent(preloads, 8);
+                       preloads.append("image").append(idx);
+                       preloads.append(".src = '").append(s).append("'\n");
+                       idx++;
+               }
+               
+               StringBuffer contents = new StringBuffer();
+               for (MapArea area : areas) {
+                       contents.append('\n');
+                       area.export(contents, 8);
+               }
+               
+               Map<String, String> subs = new HashMap<String, String>();
+               subs.put("image-name", imageName);
+               subs.put("page-title", pageTitle);
+               subs.put("image-href", imageHref);
+               subs.put("image-alt", imageAlt);
+               subs.put("map-name", mapName);
+               subs.put("contents", contents.toString());
+               subs.put("preloads", preloads.toString());
+               
+               return substitute(template, subs);
+       }
+       
+       public void exportToFile(File file) throws IOException {
+               FileWriter writer = new FileWriter(file);
+               try {
+                       writer.append(export());
+               } finally {
+                       writer.close();
+               }
+       }
+       
+       private String substitute(String template, Map<String, String> subs) {
+               // This could be more efficient..
+               String result = template;
+               for (String key : subs.keySet()) {
+                       String regex = String.format("\\$\\{%s\\}", key);
+                       result = result.replaceAll(regex, subs.get(key));
+               }
+               
+               return result;
+       }
+       
+       private String loadTemplate() {
+               BufferedReader reader = new BufferedReader(new InputStreamReader(
+                               getClass().getResourceAsStream(TEMPLATE_FILE)));
+               
+               StringBuffer buff = new StringBuffer();
+               
+               try {
+                       String line;
+                       while ((line = reader.readLine()) != null) {
+                               buff.append(line).append('\n');
+                       }
+               } catch (IOException e) {
+                       throw new RuntimeException(e);
+               } finally {
+                       try {
+                               reader.close();
+                       } catch (IOException e) {
+                               // Ignore
+                       }
+               }
+               
+               return buff.toString();
+       }
+       
+       public String toString() {
+               return export();
+       }
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/export/imagemap/MapArea.java b/Annotation/src/ie/dcu/apps/ist/export/imagemap/MapArea.java
new file mode 100644 (file)
index 0000000..2bc22b3
--- /dev/null
@@ -0,0 +1,133 @@
+/**
+ * 
+ */
+package ie.dcu.apps.ist.export.imagemap;
+
+import java.awt.Polygon;
+import java.awt.Rectangle;
+import java.net.*;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+
+public class MapArea {
+       
+       private String href;
+       private String alt;
+       private AreaShape shape;
+       private int[] coords;
+       private final Map<String, String> attrs;
+       
+       public MapArea() {
+               href = "";
+               alt = "";
+               shape = AreaShape.Polygon;
+               coords = new int[0];
+               attrs = new HashMap<String, String>();
+       }
+       
+       public void addAttr(String key, String value) {
+               attrs.put(key, value);
+       }
+
+       public String getHref() {
+               return href;
+       }
+
+       public void setHref(String href) {
+               this.href = href == null ? "" : href;
+       }
+
+       public String getAlt() {
+               return alt;
+       }
+
+       public void setAlt(String alt) {
+               this.alt = alt == null ? "" : alt;
+       }
+       
+       public AreaShape getShape() {
+               return shape;
+       }
+
+       public void setShape(AreaShape shape) {
+               this.shape = shape == null ? AreaShape.Polygon : shape;
+       }
+
+       public int[] getCoords() {
+               return coords;
+       }
+
+       public void setCoords(int[] coords) {
+               this.coords = coords == null ? new int[0] : coords;
+       }
+
+       public void setRect(Rectangle rect) {
+               setShape(AreaShape.Rectangle);
+               int[] coords = {
+                               rect.x, 
+                               rect.y, 
+                               rect.x + rect.width, 
+                               rect.y + rect.height
+               };
+               setCoords(coords);
+       }
+       
+       public void setCircle(int x, int y, int r) {
+               setShape(AreaShape.Circle);
+               int[] coords = { x, y, r };
+               setCoords(coords);
+       }
+       
+       public void setPolygon(Polygon poly) {
+               setShape(AreaShape.Polygon);
+               int[] coords = new int[2*poly.npoints];
+               for (int i = 0, j = 0; i < poly.npoints; i++) {
+                       coords[j++] = poly.xpoints[i];
+                       coords[j++] = poly.ypoints[i];
+               }
+               setCoords(coords);
+       }
+       
+       public void export(StringBuffer sb, int indent) {
+               String encodedHREF = href;
+               if (href.length() != 0) {
+                       try {
+                               URI uri = new URI(href);
+                               URL url = uri.toURL();
+                               encodedHREF = url.toString();
+                       } catch (URISyntaxException e) {
+                               // Ignore exceptions, the href string will be used instead
+                       } catch (MalformedURLException e) {
+                               // Ignore exceptions, the href string will be used instead
+                       }
+               }
+               
+               HtmlTag tag = new HtmlTag("area");
+               tag
+                 .attr("href", encodedHREF)
+                 .attr("alt", alt)
+                 .attr("shape", shape.toString())
+                 .attr("coords", getCoordsString());
+               
+               for (Entry<String, String> entry : attrs.entrySet()) {
+                       tag.attr(entry.getKey(), entry.getValue());
+               }
+               
+               tag.open(sb, indent, true);
+       }
+       
+       public String getCoordsString() {
+               StringBuffer sb = new StringBuffer();
+               boolean first = true;
+               for (int coord : coords) {
+                       if (!first) {
+                               sb.append(',');
+                       }
+                       sb.append(coord);
+                       first = false;
+               }
+               return sb.toString();
+       }
+}
\ No newline at end of file
diff --git a/Annotation/src/ie/dcu/apps/ist/export/imagemap/RolloverEffect.java b/Annotation/src/ie/dcu/apps/ist/export/imagemap/RolloverEffect.java
new file mode 100644 (file)
index 0000000..8e5ea2b
--- /dev/null
@@ -0,0 +1,191 @@
+package ie.dcu.apps.ist.export.imagemap;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.Polygon;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.Stroke;
+import java.awt.geom.Area;
+import java.awt.image.BufferedImage;
+import java.awt.image.RenderedImage;
+
+/**
+ * The roll-over effect for the image map.
+ * 
+ * @author Kevin McGuinness
+ */
+public abstract class RolloverEffect {
+       
+       public abstract RenderedImage createEffect(Image image, Polygon object);
+       
+       public static RolloverEffect darkenBackground(float alpha) {
+               return new DarkenBackground(alpha);
+       }
+       
+       public static RolloverEffect darkenBackground() {
+               return new DarkenBackground();
+       }
+       
+       public static RolloverEffect brightenForeground(float alpha) {
+               return new BrightenForeground(alpha);
+       }
+       
+       public static RolloverEffect brightenForeground() {
+               return new BrightenForeground();
+       }
+       
+       public static RolloverEffect outlineObject() {
+               return new OutlineObject();
+       }
+       
+       public static RolloverEffect outlineObject(Color color) {
+               return new OutlineObject(color);
+       }
+       
+       public static RolloverEffect outlineObject(Color color, Stroke stroke) {
+               return new OutlineObject(color, stroke);
+       }
+       
+       public static class DarkenBackground extends RolloverEffect {
+               
+               private float alpha = 0.5f;
+               
+               public DarkenBackground() {
+                       
+               }
+
+               public DarkenBackground(float alpha) {
+                       this.alpha = alpha;
+               }
+
+               public float getAlpha() {
+                       return alpha;
+               }
+
+               public void setAlpha(float alpha) {
+                       this.alpha = alpha;
+               }
+
+               @Override
+               public RenderedImage createEffect(Image image, Polygon object) {
+                       int width = image.getWidth(null);
+                       int height = image.getHeight(null);
+                       BufferedImage im = new BufferedImage(width, height, 
+                                       BufferedImage.TYPE_INT_ARGB);
+                       
+                       Area area = new Area(new Rectangle(0,0,width,height));
+                       area.subtract(new Area(object));
+                       
+                       Graphics g = im.getGraphics();
+                       if (g instanceof Graphics2D) {
+                               Graphics2D g2 = (Graphics2D) g;
+                               g2.drawImage(image, 0, 0, null);
+                               g2.setColor(new Color(0,0,0,alpha));
+                               g2.fill(area);
+                       }
+                       
+                       return im;
+               }
+       }
+       
+       public static class BrightenForeground extends RolloverEffect {
+               
+               private float alpha = 0.5f;
+               
+               public BrightenForeground() {
+                       
+               }
+
+               public BrightenForeground(float alpha) {
+                       this.alpha = alpha;
+               }
+
+               public float getAlpha() {
+                       return alpha;
+               }
+
+               public void setAlpha(float alpha) {
+                       this.alpha = alpha;
+               }
+
+               @Override
+               public RenderedImage createEffect(Image image, Polygon object) {
+                       int width = image.getWidth(null);
+                       int height = image.getHeight(null);
+                       BufferedImage im = new BufferedImage(width, height, 
+                                       BufferedImage.TYPE_INT_ARGB);
+                       
+                       Graphics g = im.getGraphics();
+                       if (g instanceof Graphics2D) {
+                               Graphics2D g2 = (Graphics2D) g;
+                               g2.drawImage(image, 0, 0, null);
+                               g2.setColor(new Color(1,1,1,alpha));
+                               g2.fill(object);
+                       }
+                       
+                       return im;
+               }
+       }
+       
+       public static class OutlineObject extends RolloverEffect {
+               
+               private Color color = Color.white;
+               private Stroke stroke = new BasicStroke(2.0f, 
+                               BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
+               
+               public OutlineObject() {
+                       
+               }
+
+               public OutlineObject(Color color) {
+                       this.color = color;
+               }
+               
+               public OutlineObject(Color color, Stroke stroke) {
+                       this.color = color;
+                       this.stroke = stroke;
+               }
+
+               public Color getColor() {
+                       return color;
+               }
+
+               public void setColor(Color color) {
+                       this.color = color;
+               }
+
+               public Stroke getStroke() {
+                       return stroke;
+               }
+
+               public void setStroke(Stroke stroke) {
+                       this.stroke = stroke;
+               }
+
+               @Override
+               public RenderedImage createEffect(Image image, Polygon object) {
+                       int width = image.getWidth(null);
+                       int height = image.getHeight(null);
+                       BufferedImage im = new BufferedImage(width, height, 
+                                       BufferedImage.TYPE_INT_ARGB);
+                       
+                       Graphics g = im.getGraphics();
+                       if (g instanceof Graphics2D) {
+                               Graphics2D g2 = (Graphics2D) g;
+                               g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
+                                               RenderingHints.VALUE_ANTIALIAS_ON);
+                               g2.drawImage(image, 0, 0, null);
+                               g2.setColor(color);
+                               g2.setStroke(stroke);
+                               g2.draw(object);
+                       }
+                       
+                       return im;
+               }
+       }
+}
+
diff --git a/Annotation/src/ie/dcu/apps/ist/export/imagemap/template.html b/Annotation/src/ie/dcu/apps/ist/export/imagemap/template.html
new file mode 100644 (file)
index 0000000..159d2a1
--- /dev/null
@@ -0,0 +1,38 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
+       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html>
+<head>
+    <!-- Generated using the CDVP Interactive Segmentation Tool -->
+    <meta http-equiv="Content-type" 
+          content="text/html; charset=utf-8"/>
+    <meta name="Generator" 
+          content="Interactive Segmentation Tool"/>
+    
+    <title>${page-title}</title>
+    
+    <script type="text/javascript" language="javascript">
+               
+${preloads}
+               
+        function rollover(docElem, image) {
+            docElem.src = image.src
+            return true
+        }
+        
+    </script>
+  
+</head>
+<body>
+    <!-- Image -->
+    <img name="${image-name}"
+         src="${image-href}" 
+         usemap="#${map-name}" 
+         alt="${image-alt}"
+         title="${image-alt}"/>
+    
+    <!-- Image map -->
+    <map name="${map-name}" id="${map-name}">
+${contents}
+    </map>
+</body>
+</html>
\ No newline at end of file
diff --git a/Annotation/src/ie/dcu/apps/ist/recent/RecentFiles.java b/Annotation/src/ie/dcu/apps/ist/recent/RecentFiles.java
new file mode 100644 (file)
index 0000000..16ef717
--- /dev/null
@@ -0,0 +1,234 @@
+package ie.dcu.apps.ist.recent;
+
+import java.io.*;
+import java.util.*;
+import java.util.logging.*;
+
+/**
+ * Class for managing a recent documents list.
+ * 
+ * @author Kevin McGuinness
+ */
+public class RecentFiles implements Iterable<File> {
+       public static final int DEFAULT_CAPACITY = 10;
+       
+       
+       private final LinkedList<File> history;
+       private final List<RecentFilesListener> listeners;
+       private final File store;
+       private int capacity;
+       
+       
+       public RecentFiles(File store) {
+               
+               // Check the store is ok
+               checkValid(store);
+               
+               // Construct
+               this.history = new LinkedList<File>();
+               this.listeners = new LinkedList<RecentFilesListener>();
+               this.store = store;
+               this.capacity = DEFAULT_CAPACITY;
+               
+               // Add a vm shutdown hook
+               addShutdownHook();
+       }
+       
+       
+       public void setCapacity(int capacity) {
+               
+               // Check positive
+               if (capacity < 0) {
+                       throw new IllegalArgumentException("capacity < 0");
+               }
+               
+               if (this.capacity != capacity) {
+                       this.capacity = capacity;
+               
+                       // Capacity may have reduced
+                       boolean reduced = history.size() > capacity;
+                       while (history.size() > capacity) {
+                               history.removeLast();
+                       }
+                       
+                       // Fire change
+                       if (reduced) {
+                               fireHistoryChanged();
+                       }
+               }
+       }
+       
+       
+       public int getCapacity() {
+               return capacity;
+       }
+       
+
+       public void add(File file) {
+               if (!history.contains(file)) {
+                       history.addFirst(file);
+                       
+                       // Check if we have exceeded capacity
+                       if (history.size() > capacity) {
+                               history.removeLast();
+                       }
+                       
+                       // Fire change
+                       fireHistoryChanged();
+               }
+       }
+       
+       
+       public void clear() {
+               if (!empty()) {
+                       history.clear();
+                       fireHistoryChanged();
+               }
+       }
+
+
+       public List<File> files() {
+               return Collections.unmodifiableList(history);
+       }
+
+
+       public Iterator<File> iterator() {
+               return files().iterator();
+       }
+
+
+       public boolean empty() {
+               return history.isEmpty();
+       }
+
+
+       public void load() throws IOException {
+               if (!store.exists()) {
+                       // Create an empty store
+                       store.createNewFile();
+               }
+               
+               BufferedReader in = null;
+               try {
+                       read(in = new BufferedReader(new FileReader(store)));
+               
+               } finally {
+                       in.close();
+               }
+       }
+
+
+       public void store() throws IOException {
+               PrintWriter out = null;
+               try {
+                       write(out = new PrintWriter(store));
+                       
+               } finally {
+                       out.close();
+               }
+       }
+
+
+       public void addListener(RecentFilesListener rfl) {
+               listeners.add(rfl);
+       }
+       
+       
+       public void removeListener(RecentFilesListener rfl) {
+               listeners.remove(rfl);
+       }
+       
+
+       protected static Logger getLogger() {
+               return Logger.getLogger(RecentFiles.class.getName());
+       }
+
+
+       private void shutdown() {
+               try {
+                       store();
+               } catch (IOException e) {
+                       getLogger().warning("Error writing recent documents to store: " + e);
+               }
+       }
+
+
+       private void fireHistoryChanged() {
+               RecentFilesEvent evt = null;
+               for (RecentFilesListener listener : listeners) {
+                       if (evt == null) {
+                               evt = new RecentFilesEvent(this);
+                               listener.historyChanged(evt);
+                       }
+               }
+       }
+
+
+       private void checkValid(File store) {
+               if (store == null) {
+                       throw new IllegalArgumentException("store cannot be null");
+               }
+               
+               if (store.isDirectory()) {
+                       throw new IllegalArgumentException("store cannot be a directory");
+               }
+               
+               if (store.isFile()) {
+                       if (!store.canWrite()) {
+                               throw new IllegalArgumentException("store not writable");
+                       }
+               }
+       }
+
+
+       private void addShutdownHook() {
+               Runtime.getRuntime().addShutdownHook(new Thread() {
+                       public void run() {
+                               shutdown();
+                       }
+               });
+       }
+
+
+       private void read(BufferedReader in) throws IOException {
+               
+               // Remember old history to check for changes
+               LinkedList<File> old = new LinkedList<File>(history);
+               
+               // Clear history if not empty
+               history.clear();
+               
+               // Read files (discarding no longer existent ones)
+               String line;
+               while ((line = in.readLine()) != null) {
+                       
+                       // Stop when full
+                       if (history.size() == capacity) {
+                               break;
+                       }
+                       
+                       File file = new File(line);
+                       if (file.exists()) {
+                               history.add(file);
+                       }
+               }
+               
+               // Fire change if a change occurred
+               if (!history.equals(old)) {
+                       fireHistoryChanged();
+               }
+       }
+
+
+       private void write(PrintWriter out) throws IOException {
+               for (File file : history) {
+                       String path = file.getAbsolutePath();
+                       out.println(path);
+               }
+               
+               // Check for errors
+               if (out.checkError()) {
+                       throw new IOException("Error writing to file");
+               }
+       }
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/recent/RecentFilesEvent.java b/Annotation/src/ie/dcu/apps/ist/recent/RecentFilesEvent.java
new file mode 100644 (file)
index 0000000..8b0932e
--- /dev/null
@@ -0,0 +1,17 @@
+package ie.dcu.apps.ist.recent;
+
+import java.util.*;
+
+public class RecentFilesEvent extends EventObject {
+       private static final long serialVersionUID = 1L;
+
+       
+       public RecentFilesEvent(RecentFiles source) {
+               super(source);
+       }
+
+       
+       public RecentFiles getList() {
+               return (RecentFiles) source;
+       }
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/recent/RecentFilesListener.java b/Annotation/src/ie/dcu/apps/ist/recent/RecentFilesListener.java
new file mode 100644 (file)
index 0000000..8d50258
--- /dev/null
@@ -0,0 +1,8 @@
+package ie.dcu.apps.ist.recent;
+
+import java.util.*;
+
+public interface RecentFilesListener extends EventListener {
+
+       public void historyChanged(RecentFilesEvent evt);
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/views/ExperimentPanel.java b/Annotation/src/ie/dcu/apps/ist/views/ExperimentPanel.java
new file mode 100644 (file)
index 0000000..94dc2e3
--- /dev/null
@@ -0,0 +1,547 @@
+/**
+ * 
+ */
+package ie.dcu.apps.ist.views;
+
+import ie.dcu.apps.ist.AppWindow;
+import ie.dcu.apps.ist.event.*;
+import ie.dcu.apps.ist.exp.*;
+import ie.dcu.apps.ist.widgets.SwtTimer;
+import ie.dcu.segment.annotate.*;
+
+import java.io.IOException;
+import java.util.Properties;
+import java.util.logging.*;
+
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+
+/**
+ * @author Kevin McGuinness
+ */
+public class ExperimentPanel extends Composite {
+       
+       // Some property keys
+       private static final String DESCRIPTION_TITLE 
+               = "description.title";
+       
+       private static final String TIMEOUT_MESSAGE 
+               = "timeout-message";
+       
+       private static final String EXPERIMENT_COMPLETE_MESSAGE 
+               = "experiment-complete-message";
+
+       // Type of button in use
+       private static enum ButtonType { Start, Finish };
+       
+       // App window and experiment
+       private final AppWindow window;
+       private final Experiment experiment;
+       private final Logger log;
+       
+       // Controls
+       private final Group group;
+       private final Button button;
+       private final SwtTimer timer;
+       private final Text text;
+       
+       // Shell if the panel is inside a shell
+       private Shell shell;
+       
+       // Experiment manager
+       private final ExperimentManager manager;
+       private final EvaluationListener evaluator;
+       
+       
+       public ExperimentPanel(AppWindow window, Composite parent, int style) {
+               super(parent, style);
+       
+               // Set app window
+               this.window = window;
+               this.experiment = window.getExperiment();
+               this.log = Logger.getLogger("Experiment");
+               
+               
+               // Create controls
+               timer  = new SwtTimer(this, SWT.NONE);
+               group = new Group(this, SWT.DEFAULT);
+               button = new Button(this, SWT.PUSH);
+               text   = new Text(group, SWT.READ_ONLY | SWT.WRAP); 
+               
+               // Create manager and evaluator
+               manager = new ExperimentManager(window);
+               evaluator = new EvaluationListener(manager, timer);
+               
+               // Setup controls
+               setupControls();
+               layoutControls();
+               addListeners();
+               
+               // Begin experiment
+               beginExperiment();
+       }
+       
+       
+       public static void open(AppWindow win) {
+               Shell app = win.getShell();
+               
+               // Style bits
+               int style = SWT.MODELESS | SWT.RESIZE | SWT.BORDER | SWT.TITLE | SWT.CLOSE;
+               
+               // Construct shell
+               Shell shell = new Shell(app, style);
+               
+               // Determine shell bounds
+               Rectangle bounds = new Rectangle(0,0,180,280);
+               
+               // Move shell to an appropriate place (right of app window)
+               Rectangle rect = app.getBounds();
+               bounds.x = rect.x + rect.width;
+               bounds.y = rect.y + rect.height / 2 - bounds.height / 2;
+               
+               // Move back if outside the screen
+               Rectangle screen = shell.getDisplay().getBounds();
+               if (bounds.x + bounds.width > screen.width) {
+                       bounds.x -= bounds.x + bounds.width - screen.width;
+               }
+
+               // Set bounds
+               shell.setBounds(bounds);
+       
+               // Set layout
+               shell.setLayout(new FillLayout());
+               
+               // Create experiment panel
+               final ExperimentPanel panel 
+                       = new ExperimentPanel(win, shell, SWT.NONE);
+               
+               panel.shell = shell;
+               panel.updateTitle();
+               
+               // Add shell close button listener
+               shell.addShellListener(new ShellAdapter() {
+                       public void shellClosed(ShellEvent e) {
+                               if (!panel.manager.isComplete()) {
+                                       e.doit = panel.cancelExperiment();
+                               }
+                       }
+               });
+               
+               // Open experiment panel
+               shell.open();
+       }
+
+       
+       private void setupControls() {
+               group.setText(property(DESCRIPTION_TITLE));
+               text.setEnabled(false);
+               enableButton(null);
+       }
+
+
+       private void layoutControls() {
+               GridLayout gl;
+               GridData   gd;
+               
+               // Setup layout manager for this
+               gl = new GridLayout();
+               gl.marginTop = 5;
+               gl.verticalSpacing = 5;
+               this.setLayout(gl);
+               
+               // Setup layout manager for group
+               gl = new GridLayout();
+               group.setLayout(gl);
+               
+               // Layout timer
+               gd = new GridData(SWT.FILL, SWT.FILL, true, false);
+               timer.setLayoutData(gd);
+               
+               // Layout group
+               gd = new GridData(SWT.FILL, SWT.FILL, true, true);
+               group.setLayoutData(gd);
+               
+               // Layout button
+               gd = new GridData(SWT.FILL, SWT.FILL, true, false);
+               button.setLayoutData(gd);
+               
+               // Layout text
+               gd = new GridData(SWT.FILL, SWT.FILL, true, true);
+               text.setLayoutData(gd);
+       }
+
+
+       private void addListeners() {
+               button.addListener(SWT.Selection, buttonListener);
+               timer.addTimeoutListener(timeListener);
+       }
+
+       
+       /**
+        * Function to call if something goes wrong with the experiment. Shows an
+        * error message and gracefully returns the application to normal mode.
+        * 
+        * @param reason
+        *          Short description of the problem.
+        */
+       private void abortExperiment(String reason) {
+               timer.clear();
+               evaluator.detach();
+               
+               // Show abort message
+               error("Aborting experiment!%n%s", reason);
+               
+               // Tell manager of abort
+               manager.abortExperiment();
+               
+               // Exit experiment mode
+               exitExperimentMode();
+       }
+       
+       
+       /**
+        * Does what is necessary to exit experiment mode.
+        */
+       private void exitExperimentMode() {
+               // Remove experiment view
+               window.setExperiment(null);
+               
+               // Re-enable interactions
+               window.getView().setEnabled(true);
+               
+               // Kill the shell
+               closeShell();
+       }
+       
+       
+       /**
+        * Closes the encompassing (non-application) shell, if any.
+        */
+       private void closeShell() {
+               if (shell != null) {
+                       shell.close();
+                       shell.dispose();
+                       shell = null;
+               }
+       }
+       
+       
+       private boolean cancelExperiment() {
+               // Make sure the user knows what they're doing
+               boolean cancel = MessageDialog.openQuestion(window.getShell(), "Confirm", 
+                               "Are you sure you want to cancel the experiment?");
+               
+               if (cancel) {
+                       // Guess we better do what the user says, grumble grumble :-/
+                       timer.clear();
+                       evaluator.detach();
+                       manager.abortExperiment();
+                       window.setExperiment(null);
+                       window.getView().setEnabled(true);
+               }
+               
+               return cancel;
+       }
+       
+       
+       /**
+        * Start the experiment.
+        */
+       private void beginExperiment() {
+               try {
+                       manager.beginExperiment(experiment);
+                       
+               } catch (IOException e) {
+                       log.log(Level.SEVERE, "Error starting experiment", e);
+                       abortExperiment(e.getMessage());
+               }
+               
+               // Begin first task
+               beginTask();
+       }
+       
+       
+       /**
+        * Finish the experiment.
+        */
+       private void endExperiment() {
+               try {
+                       manager.endExperiment();
+                       
+               } catch (IOException e) {
+                       log.log(Level.SEVERE, "Error ending experiment", e);
+                       abortExperiment(e.getMessage());
+               }
+               
+               // Tell user experiment is complete
+               notifyExperimentComplete();
+               
+               // Stop experiment mode
+               exitExperimentMode();
+       }
+       
+       
+       /**
+        * Load the task.
+        */
+       private void beginTask() {
+       
+               // Set timer
+               timer.set(experiment.getTime());
+               
+               // Begin task
+               try {
+                       manager.beginTask();
+               } catch (IOException e) {
+                       log.log(Level.SEVERE, "Error starting task", e);
+                       abortExperiment(e.getMessage());
+               }
+               
+               // Disable interactions
+               window.getView().setEnabled(false);
+               
+               // Update description
+               text.setText(manager.getTaskDescription());
+               
+               // Update title text
+               updateTitle();
+               
+               // Setup start button
+               enableButton(ButtonType.Start);
+               
+               // Attach evaluator
+               evaluator.attach();
+       }
+       
+       
+       private void updateTitle() {
+               if (shell != null) {
+                       int ntasks = manager.getTaskCount();
+                       int progress = manager.getProgress();
+                       shell.setText(String.format("Task [%d/%d]", progress+1, ntasks));
+               }
+       }
+
+
+       /**
+        * Start the task.
+        */
+       private void startTask() {
+               
+               // Enable interactions
+               window.getView().setEnabled(true);
+               
+               // Start clock
+               timer.start();
+               
+               // Enable finish button
+               enableButton(ButtonType.Finish);
+       }
+       
+
+       /**
+        * End the task.
+        */
+       private void endTask() {
+               // Detach evaluator
+               evaluator.detach();
+               
+               // Evaluate final result
+               manager.evaluate(timer.getElapsed());
+               
+               // End task
+               try {
+                       manager.endTask();
+               } catch (IOException e) {
+                       log.log(Level.SEVERE, "Error ending task", e);
+                       abortExperiment(e.getMessage());
+               }
+               
+               // Stop and clear clock
+               timer.clear();
+       }
+       
+       
+       /**
+        * End the current task and start the next. 
+        * End the experiment if finished.
+        */
+       private void nextTask() {
+               endTask();
+               if (manager.isComplete()) {
+                       endExperiment();
+               } else {
+                       beginTask();
+               }
+       }
+       
+
+       private void enableButton(ButtonType type) {
+               if (type != null) {
+                       String name = type.toString().toLowerCase();
+                       button.setText(property("button.text." + name));
+                       button.setData(type);
+                       button.setEnabled(true);
+                       button.setFocus();
+               } else {
+                       button.setText(property("button.text.start"));
+                       button.setEnabled(false);
+                       button.setData(null);
+               }
+       }
+       
+       
+       private ButtonType getEnabledButton() {
+               return (ButtonType) button.getData();
+       }
+
+
+       private void handleButtonClicked() {
+               ButtonType btn = getEnabledButton();
+               switch (btn) {
+               case Start:
+                       startTask();
+                       break;
+               case Finish:
+                       // Prevent clicking finish by accident
+                       if (manager.getActiveContext().getAnnotations().count() == 0) {
+                               getDisplay().beep();
+                       } else {
+                               nextTask();
+                       }
+                       break;
+               }
+       }
+
+
+       private void handleTimeout() {
+               // Finish task
+               endTask();
+               
+               // Tell user
+               notifyTimeoutOccurred();
+               
+               // Next task
+               if (manager.isComplete()) {
+                       endExperiment();
+               } else {
+                       beginTask();
+               }
+       }
+
+
+       private void notifyExperimentComplete() {
+               message(EXPERIMENT_COMPLETE_MESSAGE);
+       }
+
+
+       private void notifyTimeoutOccurred() {
+               // BEEP BEEP!! time up :-)
+               getDisplay().beep();
+               message(TIMEOUT_MESSAGE);
+       }
+
+
+       private void message(String key) {
+               Shell main = window.getShell();
+               MessageDialog.openInformation(main, "Information", property(key));
+       }
+       
+       
+       private void error(String message, Object ... args) {
+               Shell main = window.getShell();
+               MessageDialog.openError(main, "Error", String.format(message, args));
+       }
+
+
+       private String property(String key) {
+               return property(key, key);
+       }
+
+
+       private String property(String key, String def) {
+               Properties p = window.getProperties();
+               return p.getProperty(String.format("ExperimentPanel.%s", key), def);
+       }
+
+
+       private final Listener buttonListener = new Listener() {
+               public void handleEvent(Event event) {
+                       handleButtonClicked();
+               }
+       };      
+       
+       
+       private final TimeoutListener timeListener = new TimeoutListener() {
+               public void timeoutOccured(TimeoutEvent evt) {
+                       handleTimeout();
+               }
+       };
+}
+
+
+class EvaluationListener implements AnnotationListener {
+       private final ExperimentManager manager;
+       private final SwtTimer timer;
+       private final Logger log;
+       
+       public EvaluationListener(ExperimentManager manager, SwtTimer timer) {  
+               this.manager = manager;
+               this.timer = timer;
+               this.log = Logger.getLogger("Experiment");
+       }
+       
+       
+       public void attach() {
+               manager.getActiveContext().addAnnotationListener(this);
+       }
+       
+       
+       public void detach() {
+               manager.getActiveContext().removeAnnotationListener(this);
+       }
+       
+       
+       private void annotationsChanged(AnnotationEvent e) {
+               // Return if there is nothing to evaluate yet
+               if (e.manager.count() == 0) {
+                       return;
+               }
+                               
+               // Time the change occurred
+               int time = timer.getElapsed();
+               manager.evaluate(time);
+               
+               // Store if necessary
+               try {
+                       manager.store(time);
+               } catch (IOException ex) {
+                       log.log(Level.SEVERE, "Error storing intermediate segmentation mask", e);
+               }
+       }
+
+       
+       public void annotationPerformed(AnnotationEvent e) {
+               annotationsChanged(e);
+       }
+
+       
+       public void annotationRedone(AnnotationEvent e) {
+               annotationsChanged(e);
+       }
+
+       
+       public void annotationUndone(AnnotationEvent e) {
+               annotationsChanged(e);
+       }
+
+       
+       public void annotationsCleared(AnnotationEvent e) {
+               annotationsChanged(e);
+       }
+}
+
diff --git a/Annotation/src/ie/dcu/apps/ist/views/SegmentationView.java b/Annotation/src/ie/dcu/apps/ist/views/SegmentationView.java
new file mode 100644 (file)
index 0000000..5633d7d
--- /dev/null
@@ -0,0 +1,1074 @@
+package ie.dcu.apps.ist.views;
+
+
+import ie.dcu.apps.ist.PainterRegistry;
+import ie.dcu.apps.ist.event.*;
+import ie.dcu.apps.ist.widgets.*;
+import ie.dcu.segment.*;
+import ie.dcu.segment.annotate.*;
+import ie.dcu.segment.options.SegmenterOptionDialog;
+import ie.dcu.segment.painters.SegmentationPainter;
+import ie.dcu.swt.*;
+import ie.dcu.swt.event.*;
+
+import java.lang.reflect.InvocationTargetException;
+import java.net.*;
+import java.util.Properties;
+import java.util.logging.*;
+import java.io.*;
+import org.json.*;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.action.*;
+import org.eclipse.jface.operation.*;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+
+public class SegmentationView extends Composite {
+       // Logger
+       private static final Logger log = Logger.getLogger(SegmentationView.class.getName());
+       
+       
+       // Segmentation view properties
+       private final Properties props;
+       
+       
+       // Houses various painters
+       private final PainterRegistry painters;
+       
+       
+       // View handling annotations
+       private final AnnotatedImageControl view;
+       
+       
+       // Left and right tool bar
+       private final ToolBar bar1, bar2, bar3;
+       
+       private final Button assign;
+       
+       //private final StyledText text;                
+       
+       // Control to change brush size
+       private final BrushControl brushControl;
+       
+       
+       // Handles various events
+       private final EventHandler eventHandler;
+       
+       
+       // Proxy object to catch and log exceptions thrown by the segmentation
+       // algorithm, without crashing the application.
+       private RobustSegmenterProxy segmenterProxy;
+       
+       // Auto segment on update flag
+       private boolean auto = true;
+       
+       // Combo box housing the selectable views
+       private Combo combo;
+
+       public static Combo comboLabel;
+       
+       // Current segmentation tool
+       private Segmenter segmenter;
+       
+       
+       // Context to run the segmentation in, (may be null)
+       private IRunnableContext runnableContext;
+       
+       
+       // Flag to indicate that the runnable context blocks when fork is true
+       private boolean blocksOnFork;
+       
+       
+       public enum Tool {
+               Foreground,
+               Background,
+               ZoomIn,
+               ZoomOut,
+               ZoomOriginal,
+               ZoomBestFit,
+               Repaint,
+               Undo,
+               Redo,
+               Clear,
+               SetBrushSize,
+               AutoApply,
+               Apply,
+               SetPainter,
+               SetLabel,
+               AssignButton,
+               SegmenterOptions;
+               
+               private ToolAction action;
+       };
+       
+       
+       public SegmentationView(Properties props, Composite parent, int style) {
+               super(parent, style);
+               this.props = props;
+               
+               painters = new PainterRegistry();
+               bar1 = new ToolBar(this, SWT.RIGHT | SWT.FLAT);
+               bar2 = new ToolBar(this, SWT.RIGHT | SWT.FLAT);
+               bar3 = new ToolBar(this, SWT.RIGHT | SWT.FLAT);
+               assign = new Button(bar3, SWT.PUSH);
+               view = new AnnotatedImageControl(this, SWT.BORDER);
+               brushControl = new BrushControl(getShell(), SWT.BORDER);
+               eventHandler = new EventHandler();
+               segmenterProxy = new RobustSegmenterProxy();
+               
+               init();
+       }
+
+
+       /**
+        * Initialize.
+        */
+       private void init() {
+               initTools();
+               createToolbar1();
+               createToolbar2();
+               createToolbar3();
+               layoutControls();
+               updatePainters();
+               addListeners();
+               updateToolStates();
+       }
+
+
+       private void initTools() {
+               for (Tool t : Tool.values()) {
+                       if (t.action == null) {
+                               new ToolAction(t);
+                       }
+               }
+       }
+
+
+       private void addListeners() {
+               brushControl.addSelectionListener(eventHandler);
+               view.addContextChangeListener(eventHandler);
+               view.addZoomListener(eventHandler);
+               addDisposeListener(eventHandler);
+       }
+
+
+       private void createToolbar1() {
+               ToolBarManager m = new ToolBarManager(bar1);
+               m.add(getAction(Tool.Foreground));
+               m.add(getAction(Tool.Background));
+               m.add(new Separator());
+               m.add(getAction(Tool.ZoomIn));
+               m.add(getAction(Tool.ZoomOut));
+               m.add(getAction(Tool.ZoomOriginal));
+               m.add(getAction(Tool.ZoomBestFit));
+               m.add(new Separator());
+               m.add(getAction(Tool.Repaint));
+               m.add(getAction(Tool.Undo));
+               m.add(getAction(Tool.Redo));
+               m.add(getAction(Tool.Clear));
+               m.add(new Separator());
+               m.add(getAction(Tool.SetBrushSize));
+               m.add(new Separator());
+               m.add(getAction(Tool.AutoApply));
+               m.add(getAction(Tool.Apply));
+               m.add(getAction(Tool.SegmenterOptions));
+               m.update(true);
+       }
+       
+       
+       private void createToolbar2() {
+               SwtUtils.addLabel(bar2, getAction(Tool.SetPainter).getText());
+               combo = SwtUtils.addCombo(bar2, 115, SWT.READ_ONLY);
+               combo.setToolTipText( getAction(Tool.SetPainter).getToolTipText());
+               combo.addSelectionListener(new SelectionAdapter() {
+                       public void widgetSelected(SelectionEvent e) {
+                               execute(Tool.SetPainter, null);
+                       }
+               });
+               bar2.pack();
+       }
+       /**
+        * Third tool bar for holding the Annotate Combo box. 
+        */
+       private void createToolbar3() {
+               SwtUtils.addLabel(bar3, getAction(Tool.SetLabel).getText());
+               comboLabel = SwtUtils.addCombo(bar3, 130, SWT.SIMPLE);
+               comboLabel.setToolTipText( getAction(Tool.SetLabel).getToolTipText());
+               comboLabel.addKeyListener(new KeyListener() {
+                       @Override
+                       public void keyReleased(KeyEvent e) {
+                               comboLabel.remove(0,comboLabel.getItemCount()-1);
+                               setLabel(comboLabel.getText());
+                               Display.getCurrent().asyncExec(new Runnable() {
+                               public void run() {
+                                       comboLabel.setText(comboLabel.getText());
+                                       comboLabel.forceFocus();
+                                       }
+                               });
+                       }
+                       @Override
+                       public void keyPressed(KeyEvent arg0) {
+                               // TODO Auto-generated method stub
+                       }
+               });
+               ToolItem item = new ToolItem(bar3, SWT.SEPARATOR);
+               assign.setText("Assign");
+               item.setWidth(50);
+               item.setControl(assign);
+               assign.addSelectionListener(new SelectionListener() {
+        public void widgetSelected(SelectionEvent arg0) {
+               String lab = null;
+               if(comboLabel.getText().indexOf('{') != -1)
+               {
+                       lab = comboLabel.getText().substring(0,comboLabel.getText().indexOf('{')-1);
+               }
+               else
+               {
+                       lab = comboLabel.getText();
+               }
+               System.out.println("selected"+lab);
+               execute(Tool.AssignButton, null);
+               }
+               @Override
+               public void widgetDefaultSelected(SelectionEvent arg0) {
+                       // TODO Auto-generated method stub
+               }
+               });
+               bar3.pack();
+       }
+       
+       
+       private void layoutControls() {
+               GridLayout layout = new GridLayout(3, false);
+               layout.marginHeight = 1;
+               layout.marginWidth = 2;
+               layout.horizontalSpacing = -1; // zero leaves 1 pixel gap
+               layout.verticalSpacing = 1;
+               setLayout(layout);
+               
+               Point sz1 = bar1.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+               Point sz2 = bar2.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+               
+               int heightHint = Math.max(sz1.y, sz2.y);
+               
+               // Layout toolbar 1
+               GridData gd = new GridData();
+               gd.grabExcessHorizontalSpace = true;
+               gd.horizontalAlignment = SWT.FILL;
+               gd.heightHint = heightHint;
+               bar1.setLayoutData(gd);
+               
+               // Layout toolbar 2
+               gd = new GridData();
+               gd.horizontalAlignment = SWT.FILL;
+               gd.heightHint = heightHint;
+               bar2.setLayoutData(gd);
+               
+               // Layout view
+               gd = new GridData();
+               gd.verticalIndent = 2;
+               gd.horizontalSpan = 3;
+               gd.grabExcessHorizontalSpace = true;
+               gd.grabExcessVerticalSpace = true;
+               gd.horizontalAlignment = SWT.FILL;
+               gd.verticalAlignment = SWT.FILL;
+               view.setLayoutData(gd);
+       }
+       
+       
+       private void updatePainters() {
+               combo.removeAll();
+               boolean first = true;
+               for (SegmentationPainter p : painters.values()) {
+                       combo.add(p.getName());
+                       if (first) {
+                               combo.setText(p.getName());
+                               first = false;
+                       }
+               }
+       }
+       
+       
+       public void setSegmenter(Segmenter segmenter) {
+               if (this.segmenter != segmenter) {
+                       SegmentationContext ctx = view.getContext();
+                       
+                       if (this.segmenter != null && ctx != null) {
+                               // Finish old segmentation
+                               segmenterProxy.finish(ctx);
+                               
+                               // Remove old segmenter
+                               this.segmenter = null;
+                       }
+                       
+                       // Set new segmenter
+                       this.segmenter = segmenter;
+                       
+                       // Initialize a new segmentation
+                       start(ctx);
+                       
+                       // Update enabled buttons
+                       updateToolStates();
+               }
+       }
+       
+       
+       public Segmenter getSegmenter() {
+               return segmenter;
+       }
+       
+       
+       public void setContext(SegmentationContext ctx) {
+               
+               // context change handler handles initialization etc. 
+               // of segmenter and context
+               view.setContext(ctx);
+       }
+
+       
+       public SegmentationContext getContext() {
+               return view.getContext();
+       }
+       
+
+       public void setAnnotationType(AnnotationType type) {
+               view.setAnnotationType(type);
+       }
+       
+       
+       public Canvas getCanvas() {
+               return view.getCanvas();
+       }
+       
+       
+       public ImageControl getImageControl() {
+               return view.getImageControl();
+       }
+
+
+       public void zoomIn() {
+               view.zoomIn();
+       }
+
+
+       public void zoomOut() {
+               view.zoomOut();
+       }
+
+
+       public void zoomOriginal() {
+               view.zoomOriginal();
+       }
+
+
+       public void zoomBestFit() {
+               view.zoomBestFit();
+       }
+
+
+       public void repaint() {
+               view.repaint();
+       }
+
+
+       public void undo() {
+               view.undo();
+       }
+
+
+       public void redo() {
+               view.redo();
+       }
+
+
+       public void clear() {
+               view.clear();
+       }
+
+
+       public void setBrushSize(int size) {
+               view.setLineWidth(size);
+       }
+
+
+       public void setPainter(SegmentationPainter painter) {
+               view.setPainter(painter);
+               combo.setText(painter.getName());
+       }
+
+       
+       public SegmentationPainter getPainter() {
+               return view.getPainter();
+       }
+       
+
+       public void setAutoApply(boolean checked) {
+               if (!this.auto && checked) {
+                       // Going from off to on, resegment now
+                       apply();
+               }
+               this.auto = checked;
+       }
+       
+       
+       public boolean isAutoApply() {
+               return this.auto;
+       }
+
+
+       public boolean canZoomIn() {
+               return view.canZoomIn();
+       }
+
+
+       public boolean canZoomOut() {
+               return view.canZoomOut();
+       }
+
+
+       public boolean canZoomOriginal() {
+               return view.canZoomOriginal();
+       }
+
+
+       public boolean canZoomBestFit() {
+               return view.canZoomBestFit();
+       }
+
+
+       public boolean canUndo() {
+               return view.canUndo();
+       }
+
+
+       public boolean canRedo() {
+               return view.canRedo();
+       }
+
+
+       public boolean canClear() {
+               return view.canClear();
+       }
+       
+       
+       public boolean canShowOptions() {
+               if (hasSegmenter()) {
+                       return segmenter.getOptions().size() > 0;
+               }
+               return false;
+       }
+
+
+       public Action getAction(Tool t) {
+               return t.action;
+       }
+
+
+       public void showSegmenterOptions() {
+               if (canShowOptions()) {
+                       SegmenterOptionDialog dialog = 
+                               new SegmenterOptionDialog(getShell(), segmenter);
+               
+                       int result = dialog.open();
+                       switch (result) {
+                       case SegmenterOptionDialog.OK:
+                               // Re-segment
+                               apply();
+                       }
+               }
+       }
+       
+       
+       public boolean hasSegmenter() {
+               return segmenter != null;
+       }
+       
+
+       public void performSegmentation(AnnotationEvent e, SegmentationContext ctx) {
+               
+               if (runnableContext == null) {
+                       segment(e, ctx);
+               } else {
+                       segmentWithRunnableContext(e, ctx);
+               }
+               
+               // Repaint everything
+               repaint();
+               
+       }
+       
+       
+       public void setRunnableContext(IRunnableContext context, boolean blocksOnFork) {
+               runnableContext = context;
+               this.blocksOnFork = blocksOnFork;
+       }
+       
+       
+       public void addContextChangeListener(ContextChangeListener listener) {
+               view.addContextChangeListener(listener);
+       }
+       
+       
+       public void removeContextChangeListener(ContextChangeListener listener) {
+               view.removeContextChangeListener(listener);
+       }
+       
+       
+       public void setEnabled(boolean enabled) {
+               super.setEnabled(enabled);
+               bar1.setEnabled(enabled);
+               bar2.setEnabled(enabled);
+               view.setEnabled(enabled);
+               updateToolStates();
+       }
+       
+
+       private void run(boolean fork, IRunnableWithProgress runnable) {
+               boolean wasEnabled = isEnabled();
+               
+               try {
+                       // Disable interactions
+                       setEnabled(false);
+                       
+                       // Run segmentation
+                       runnableContext.run(fork, false, runnable);
+                       
+               } catch (InvocationTargetException ex) {
+                               
+                       // Can't happen without a runtime exception occurring, so re-wrap
+                       throw new RuntimeException(ex);
+                       
+               } catch (InterruptedException ex) {
+                       
+                       // Can't happen because cancellable is false
+                       throw new RuntimeException(ex);
+               
+               } finally {
+                       setEnabled(wasEnabled);
+               }
+       }
+
+
+       private void segmentWithRunnableContext(
+                       final AnnotationEvent e, 
+                       final SegmentationContext ctx) 
+       {
+               // Fork if the segmenter is slow, and only if our runnable context blocks 
+               boolean fork = blocksOnFork /*&& !segmenter.isFast()*/;
+               
+               run(fork, new IRunnableWithProgress() {
+                       public void run(IProgressMonitor monitor) {
+                               monitor.beginTask("Segmenting", IProgressMonitor.UNKNOWN);
+                               try {
+                                       segment(e, ctx);
+                               } finally {
+                                       monitor.done();
+                               }
+                       }
+               });
+       }
+
+       
+       private void start(final SegmentationContext ctx) {
+               if (ctx != null && hasSegmenter()) {
+                       if (runnableContext == null) {
+                               
+                               // No runnable context
+                               segmenterProxy.init(ctx);
+                               segmenterProxy.update(ctx);
+                                                               
+                       } else {
+                               
+                               // Run with progress monitor
+                               run(blocksOnFork, new IRunnableWithProgress() {
+                                       public void run(IProgressMonitor monitor) {
+                                               monitor.beginTask("Initializing", IProgressMonitor.UNKNOWN);
+                                               try {
+                                                       segmenterProxy.init(ctx);
+                                                       segmenterProxy.update(ctx);
+                                               } finally {
+                                                       monitor.done();
+                                               }
+                                       }
+                               });
+                               
+                       }
+                       
+                       // Repaint everything
+                       repaint();
+               }
+       }
+
+
+       private void segment(AnnotationEvent e, SegmentationContext ctx) {
+               if (hasSegmenter()) {
+                       if (e == null) {
+                               // No event triggered this, so do a full update
+                               segmenterProxy.update(ctx);
+                               
+                       } else {
+                               // Call appropriate segmenter function
+                               switch (e.type) {
+                               case Cleared:
+                                       segmenterProxy.update(ctx);
+                                       break;
+                                       
+                               case Undone:
+                                       segmenterProxy.removed(ctx, e.annotation);
+                                       break;
+                               
+                               case Redone:
+                               case Added:
+                                       segmenterProxy.added(ctx, e.annotation);
+                                       break;
+                               
+                               default:
+                                       throw new RuntimeException();
+                               }
+                       }
+               }
+       }
+
+
+       private boolean isAnnotatingBackground() {
+               return view.isAnnotatingBackground();
+       }
+       
+
+       private boolean isAnnotatingForeground() {
+               return view.isAnnotatingForeground();
+       }
+
+
+       private String getText(Tool a) {
+               return props.getProperty(getKey(a, "text"));
+       }
+
+
+       private String getToolTip(Tool a) {
+               return props.getProperty(getKey(a, "tooltip"));
+       }
+
+
+       private ImageDescriptor getImage(Tool a) {
+               String location = props.getProperty(getKey(a, "image"));
+               if (location != null) {
+                       if (location.length() == 0) {
+                               return null;
+                       }
+                       
+                       try {
+                               return ImageDescriptor.createFromURL(new URL(location));
+                       } catch (MalformedURLException e) {
+                               return null;
+                       }
+               }
+               
+               return null;
+       }
+
+
+       private static String getKey(Tool action, String object) {
+               return String.format("SegmentationView.Action.%s.%s", action, object);
+       }
+       
+       
+       private int getType(Tool a) {
+               switch (a) {
+               case Foreground:
+               case Background:
+               case AutoApply:
+                       return Action.AS_CHECK_BOX;
+               case SetBrushSize:
+                       return Action.AS_DROP_DOWN_MENU;
+               case SetPainter:
+                       return Action.AS_UNSPECIFIED;
+               default:
+                       return Action.AS_PUSH_BUTTON;
+               }
+       }
+       
+       
+       private void execute(Tool a, Event e) {
+               switch (a) {
+               case Foreground:
+                       setAnnotationType(AnnotationType.Foreground);
+                       break;
+               case Background:
+                       setAnnotationType(AnnotationType.Background);
+                       break;
+               case ZoomIn:
+                       zoomIn();
+                       break;
+               case ZoomOut:
+                       zoomOut();
+                       break;
+               case ZoomOriginal:
+                       zoomOriginal();
+                       break;
+               case ZoomBestFit:
+                       zoomBestFit();
+                       break;
+               case Repaint:
+                       repaint();
+                       break;
+               case Undo:
+                       undo();
+                       break;
+               case Redo:
+                       redo();
+                       break;
+               case Clear:
+                       clear();
+                       break;
+               case SetBrushSize:
+                       showBrushControl(e);
+                       break;
+               case AutoApply:
+                       setAutoApply(a.action.isChecked());
+                       break;
+               case Apply:
+                       apply();
+                       break;
+               case SetPainter:
+                       setPainter();
+                       break;
+               case AssignButton:
+                       assignLabel();
+                       break;
+               case SegmenterOptions:
+                       showSegmenterOptions();
+                       break;
+               }
+               
+               updateToolStates();
+       }
+       
+       
+       private void updateToolStates() {
+               if (isEnabled()) {
+                       Tool.Apply.action.setEnabled(!Tool.AutoApply.action.isChecked());
+                       Tool.Undo.action.setEnabled(canUndo());
+                       Tool.Redo.action.setEnabled(canRedo());
+                       Tool.ZoomIn.action.setEnabled(canZoomIn());
+                       Tool.ZoomOut.action.setEnabled(canZoomOut());
+                       Tool.ZoomOriginal.action.setEnabled(canZoomOriginal());
+                       Tool.ZoomBestFit.action.setEnabled(canZoomBestFit());
+                       comboLabel.setEnabled(canZoomBestFit());
+                       assign.setEnabled(canZoomBestFit() & !(comboLabel.getText().isEmpty()));
+                       Tool.Foreground.action.setChecked(isAnnotatingForeground());
+                       Tool.Background.action.setChecked(isAnnotatingBackground());
+                       Tool.Clear.action.setEnabled(canClear());
+                       Tool.AutoApply.action.setChecked(auto);
+                       Tool.SegmenterOptions.action.setEnabled(canShowOptions());
+                                               
+                       // Always enabled if view enabled
+                       Tool.SetBrushSize.action.setEnabled(true);
+                       Tool.SegmenterOptions.action.setEnabled(true);
+                       Tool.SetPainter.action.setEnabled(true);
+                       Tool.Repaint.action.setEnabled(true);
+                       Tool.Foreground.action.setEnabled(true);
+                       Tool.Background.action.setEnabled(true);
+                       Tool.AutoApply.action.setEnabled(true);
+                       
+               } else {
+                       // Everything disabled
+                       for (Tool t : Tool.values()) {
+                               t.action.setEnabled(false);
+                       }
+               }
+               
+       }
+
+       private void setPainter() {
+               SegmentationPainter painter = painters.get(combo.getText());
+               setPainter(painter);
+       }
+       /*
+        Assign the label to the segment on clicking assign button and update the image segment. 
+        */
+       private void assignLabel() {
+               SegmentationPainter painter = painters.get("Display Label");
+               setPainter(painter);
+       }
+       
+       private void setLabel(String content) {
+               try
+           {
+                       String content1 = URLEncoder.encode(content.toString(),"UTF-8");
+                       URL url = new URL("http://palea.cgrb.oregonstate.edu/services/PO_web_service.php?request_type=term_search&search_value="+content1+"&inc_synonyms&branch_filter=plant_anatomy&max=20");
+                       HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+                        BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
+               if(connection.getResponseCode() == 200)
+               {
+                       String inputLine;
+                       JSONObject object = null;
+                       while ((inputLine = in.readLine()) != null) 
+                       {
+                               object = new JSONObject(inputLine);
+                       }
+                       JSONArray array = new JSONArray(object.getString("PO_term_search_response"));
+                       String listElement;
+                       for(int i=0; i<array.length();i++)
+                       {
+                               if(array.getJSONObject(i).getString("match_type").trim().equals("synonym"))
+                               {
+                                       listElement = (array.getJSONObject(i).getString("match")+" {"+array.getJSONObject(i).getString("is_synonym_of")+"}");
+                                       comboLabel.add(listElement,i);
+                               }
+                               else if(array.getJSONObject(i).getString("match_type").equals("term"))
+                               {
+                                       listElement = array.getJSONObject(i).getString("match");
+                                       comboLabel.add(listElement,i);
+                               }
+                       }
+                       in.close();
+               }
+               else
+               {
+                       System.out.println("Response error");
+               }
+           }
+           catch(Exception ex)
+           {
+           }
+           assign.setEnabled(!(comboLabel.getText().isEmpty()));
+       }
+       
+       private void apply() {
+               performSegmentation(null, view.getContext());
+       }
+
+
+       private void showBrushControl(Event e) {
+               brushControl.showBelow(bar1, (ToolItem) e.widget);
+       }
+
+
+       /**
+        * Handles a context change in the view.
+        * 
+        * @param e
+        *          The event.
+        */
+       private void handleContextChanged(ContextChangedEvent e) {
+               if (e.oldContext != null) {
+                       e.oldContext.removeAnnotationListener(eventHandler);
+       
+                       // Finish old segmentation
+                       segmenterProxy.finish(e.oldContext);
+               }
+               
+               if (e.newContext != null) {
+                       e.newContext.addAnnotationListener(eventHandler);
+                       
+                       // Begin new segmentation (can cause deferred events
+                       // to be processed, so we async exec to ensure that
+                       // the other context change handlers are called before
+                       // deferred events are processed)
+                       final SegmentationContext ctx = e.newContext;
+                       getDisplay().asyncExec(new Runnable() {
+                               public void run() {
+                                       start(ctx);
+                               }
+                       });
+                       
+               }
+               
+               updateToolStates();
+       }
+
+
+       /**
+        * Cleans up resources when the view is disposed.
+        */
+       private void handleDisposed() {
+               
+               SegmentationContext ctx = view.getContext();
+               if (ctx != null && !ctx.isDisposed()) {
+                       
+                       // Finish any segmentation              
+                       segmenterProxy.finish(ctx);
+       
+                       // Dispose context
+                       ctx.dispose();
+               }
+               
+               // Dispose all painters
+               painters.dispose();
+       }
+
+
+       /**
+        * Tool bar action. Delegates running to the execute method.
+        */
+       private class ToolAction extends Action {
+               private final Tool tool;
+
+               public ToolAction(Tool tool) {
+                       super(SegmentationView.this.getText(tool), getType(tool));
+                       this.tool = tool;
+                       setToolTipText(SegmentationView.this.getToolTip(tool));
+                       setImageDescriptor(SegmentationView.this.getImage(tool));
+                       tool.action = this;
+               }
+               
+               public void runWithEvent(Event e) {
+                       execute(tool, e);
+               }
+       }
+       
+       
+       /**
+        * Handles various events coming from the view and toolbar controls.
+        * 
+        */
+       private final class EventHandler extends SelectionAdapter implements
+               ZoomListener, 
+               SelectionListener, 
+               ContextChangeListener, 
+               AnnotationListener,
+               DisposeListener
+       {
+               
+               public void widgetDisposed(DisposeEvent e) {
+                       handleDisposed();
+               }
+               
+
+               public void zoomChanged(ZoomEvent e) {
+                       updateToolStates();
+               }
+               
+
+               public void widgetSelected(SelectionEvent e) {
+                       setBrushSize(brushControl.getBrushSize());
+               }
+               
+
+               public void contextChanged(ContextChangedEvent e) {
+                       handleContextChanged(e);
+               }
+               
+
+               public void annotationPerformed(AnnotationEvent e) {
+                       if (!isEnabled()) {
+                               log.warning("annotation performed while not enabled");
+                       }
+                       
+                       if (auto && isEnabled()) {
+                               performSegmentation(e, view.getContext());
+                       }
+                       updateToolStates();
+               }
+
+               
+               public void annotationRedone(AnnotationEvent e) {
+                       if (!isEnabled()) {
+                               log.warning("annotation redone while not enabled");
+                       }
+                       
+                       if (auto && isEnabled()) {
+                               performSegmentation(e, view.getContext());
+                       }
+                       updateToolStates();
+               }
+
+               
+               public void annotationUndone(AnnotationEvent e) {
+                       if (!isEnabled()) {
+                               log.warning("annotation undone while not enabled");
+                       }
+                       
+                       if (auto && isEnabled()) {
+                               performSegmentation(e, view.getContext());
+                       }
+                       
+                       updateToolStates();
+               }
+
+               
+               public void annotationsCleared(AnnotationEvent e) {
+                       if (!isEnabled()) {
+                               log.warning("annotations cleared while not enabled");
+                       }
+                       
+                       if (auto && isEnabled()) {
+                               performSegmentation(e, view.getContext());
+                       }
+                       updateToolStates();
+               }
+       };
+       
+       /**
+        * Class that prevents segmentation algorithms crashing the application
+        * by catching any thrown exceptions and logging them.
+        * 
+        * @author Kevin McGuinness
+        */
+       private class RobustSegmenterProxy {
+
+               public void init(SegmentationContext ctx) {
+                       if (segmenter != null) {
+                               try {
+                                       segmenter.init(ctx);
+                               } catch (Throwable th) {
+                                       severe(th, "%s.init()", getSegmenterClassName());
+                               }
+                       }
+               }
+
+               public void update(SegmentationContext ctx) {
+                       if (segmenter != null) {
+                               try {
+                                       segmenter.update(ctx);
+                               } catch (Throwable th) {
+                                       severe(th, "%s.update()", getSegmenterClassName());
+                               }
+                       }
+               }
+
+               public void added(SegmentationContext ctx, Annotation a) {
+                       if (segmenter != null) {
+                               try {
+                                       segmenter.added(ctx, a);
+                               } catch (Throwable th) {
+                                       severe(th, "%s.added()", getSegmenterClassName());
+                               }
+                       }
+               }
+
+               public void removed(SegmentationContext ctx, Annotation a) {
+                       if (segmenter != null) {
+                               try {
+                                       segmenter.removed(ctx, a);
+                               } catch (Throwable th) {
+                                       severe(th, "%s.removed()", getSegmenterClassName());
+                               }
+                       }
+               }
+
+               public void finish(SegmentationContext ctx) {
+                       if (segmenter != null) {
+                               try {
+                                       segmenter.finish(ctx);
+                               } catch (Throwable th) {
+                                       severe(th, "%s.finish()", getSegmenterClassName());
+                               }
+                       }
+               }
+
+               public String getSegmenterClassName() {
+                       return segmenter.getClass().getSimpleName();
+               }
+               
+               private void severe(Throwable th, String message, Object ... args) {
+                       log.log(Level.SEVERE, String.format(message, args), th);
+               }
+       }
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/widgets/AnnotatedImageControl.java b/Annotation/src/ie/dcu/apps/ist/widgets/AnnotatedImageControl.java
new file mode 100644 (file)
index 0000000..89eb761
--- /dev/null
@@ -0,0 +1,414 @@
+package ie.dcu.apps.ist.widgets;
+
+
+import ie.dcu.apps.ist.controllers.AnnotationTool;
+import ie.dcu.apps.ist.event.*;
+import ie.dcu.segment.SegmentationContext;
+import ie.dcu.segment.annotate.*;
+import ie.dcu.segment.painters.*;
+import ie.dcu.swt.*;
+import ie.dcu.swt.event.ZoomListener;
+
+import java.util.*;
+import java.util.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.*;
+
+public class AnnotatedImageControl extends Composite {
+       private final List<ContextChangeListener> listeners;
+       private final ImageControl view;
+       private SegmentationContext ctx;
+       private AnnotationTool tool;
+       private SegmentationPainter painter;
+       private Cursor cursor;
+       
+       public AnnotatedImageControl(Composite parent, int style) {
+               super(parent, style);
+               setLayout(new FillLayout());
+               view = new ImageControl(this, SWT.NONE);
+               listeners = new ArrayList<ContextChangeListener>(2);
+               painter = new CombinedPainter();
+               view.getCanvas().addMouseMoveListener(cursorChanger);
+               addDisposeListener(disposeListener);
+       }
+       
+       
+       public ImageControl getImageControl() {
+               return view;
+       }
+       
+       
+       public Canvas getCanvas() {
+               return view.getCanvas();
+       }
+       
+       
+       public SegmentationPainter getPainter() {
+               return painter;
+       }
+       
+       
+       public void setPainter(SegmentationPainter painter) {
+               if (this.painter != painter) {
+                       this.painter = painter;
+                       recreate();
+               }
+       }
+       
+       
+       public SegmentationContext getContext() {
+               return ctx;
+       }
+       
+       
+       public void setContext(SegmentationContext ctx) {
+               
+               // Remember old context for event
+               SegmentationContext old = this.ctx;
+               
+               // Detach old tool
+               int lineWidth = 1;
+               if (tool != null) {
+                       lineWidth = tool.getLineWidth();
+                       tool.detach();
+                       tool = null;
+               }
+               
+               // Detach old annotation listener
+               if (ctx != null) {
+                       ctx.getAnnotations().removeAnnotationListener(listener);
+               }
+               
+               // Assign context
+               this.ctx = ctx;
+               
+               if (ctx != null) {
+                       // Attach new annotation listener
+                       AnnotationManager annotations = ctx.getAnnotations();
+                       annotations.addAnnotationListener(listener);
+                       
+                       // Attach a new annotation tool
+                       tool = new AnnotationTool(annotations, view);
+                       tool.setLineWidth(lineWidth);
+               }
+               
+               // Create the initial image
+               recreate();
+               
+               // Fire event
+               fireContextChanged(old);
+       }
+       
+
+       public int getLineWidth() {
+               if (tool != null) {
+                       return tool.getLineWidth();
+               }
+               return 1;
+       }
+       
+       
+       public void setLineWidth(int width) {
+               if (tool != null) {
+                       tool.setLineWidth(width);
+               }
+       }
+       
+       
+       public AnnotationType getAnnotationType() {
+               if (tool != null) {
+                       return tool.getType();
+               }
+               return AnnotationType.Foreground;
+       }
+       
+       
+       public void setAnnotationType(AnnotationType type) {
+               if (tool != null) {
+                       tool.setType(type);
+               }
+       }
+       
+       
+       public float getZoom() {
+               return view.getZoom();
+       }
+       
+       
+       public void setZoom(float zoom) {
+               view.setZoom(zoom);
+       }
+       
+       
+       public float getZoomStep() {
+               return view.getZoomStep();
+       }
+
+
+       public void setZoomStep(float zoomStep) {
+               view.setZoomStep(zoomStep);
+       }
+
+
+       public void zoomBestFit() {
+               view.zoomBestFit();
+       }
+
+
+       public void zoomIn() {
+               view.zoomIn();
+       }
+
+
+       public void zoomOriginal() {
+               view.zoomOriginal();
+       }
+
+
+       public void zoomOut() {
+               view.zoomOut();
+       }
+
+
+       public void undo() {
+               if (ctx != null) {
+                       ctx.getAnnotations().undo();
+               }
+       }
+       
+       
+       public void redo() {
+               if (ctx != null) {
+                       ctx.getAnnotations().redo();
+               }
+       }
+       
+       
+       public void clear() {
+               if (ctx != null) {
+                       ctx.getAnnotations().clear();
+               }
+       }
+       
+       
+       public boolean canUndo() {
+               if (ctx != null) {
+                       return ctx.getAnnotations().canUndo();
+               }
+               return false;
+       }
+       
+       
+       public boolean canRedo() {
+               if (ctx != null) {
+                       return ctx.getAnnotations().canRedo();
+               }
+               return false;
+       }
+       
+       
+       public boolean canClear() {
+               if (ctx != null) {
+                       return ctx.getAnnotations().count() > 0;
+               }
+               return false;
+       }
+       
+       
+       public boolean canZoomBestFit() {
+               return view.canZoomBestFit();
+       }
+
+
+       public boolean canZoomIn() {
+               return view.canZoomIn();
+       }
+
+
+       public boolean canZoomOriginal() {
+               return view.canZoomOriginal();
+       }
+
+
+       public boolean canZoomOut() {
+               return view.canZoomOut();
+       }
+       
+       
+       /**
+        * Redraw the entire canvas buffer.
+        */
+       public void repaint() {
+               if (ctx != null) {
+                       painter.paint(ctx, view.getImage());
+               }
+       }
+
+
+       public boolean isAnnotatingForeground() {
+               return getAnnotationType() == AnnotationType.Foreground;
+       }
+       
+       
+       public boolean isAnnotatingBackground() {
+               return getAnnotationType() == AnnotationType.Background;
+       }
+       
+       
+       public void addAnnotationListener(AnnotationListener listener) {
+               if (ctx == null) {
+                       throw new IllegalStateException();
+               }
+               ctx.getAnnotations().addAnnotationListener(listener);
+       }
+       
+
+       public void removeAnnotationListener(AnnotationListener listener) {
+               if (ctx != null) {
+                       ctx.getAnnotations().removeAnnotationListener(listener);
+               }
+       }
+       
+       
+       public void addZoomListener(ZoomListener listener) {
+               view.addZoomListener(listener);
+       }
+       
+       
+       public void removeZoomListener(ZoomListener listener) {
+               view.removeZoomListener(listener);
+       }
+       
+       
+       public void addContextChangeListener(ContextChangeListener listener) {
+               listeners.add(listener);
+       }
+       
+       
+       public void removeContextChangeListener(ContextChangeListener listener) {
+               listeners.remove(listener);
+       }
+       
+       
+       private void fireContextChanged(SegmentationContext old) {
+               ContextChangedEvent e = null;
+               for (ContextChangeListener l : listeners) {
+                       if (e == null) {
+                               e = new ContextChangedEvent(this, old, ctx);
+                       }
+                       l.contextChanged(e);
+               }
+       }
+       
+       
+       /**
+        * Re-construct the display image buffer, and dispose the old one if
+        * necessary. If the context is <code>null</code>, then set the display
+        * buffer to null and dispose of the old one.
+        */
+       private void recreate() {
+               if (ctx == null) {
+                       
+                       // Set null image (disposing the old one)
+                       view.setImage(null, true);
+                       
+               } else {
+                       
+                       // Check if we can reuse what we have
+                       boolean sameSize = false;
+                       if (view.hasImage()) {
+                               if (view.getImageBounds().equals(ctx.getBounds())) {
+                                       
+                                       // Okay, we can reuse the buffer we have :-)
+                                       sameSize = true;
+                               }
+                       }
+
+                       if (!sameSize) {
+               
+                               // Create initial image
+                               ObservableImage buffer = new ObservableImage(
+                                               SwtUtils.createImage(ctx.getBounds())
+                               );
+                               
+                               // Set the image (disposing the old one)
+                               view.setImage(buffer, true);
+                       }
+                       
+                       // Draw the image
+                       repaint();
+               }
+       }
+       
+       
+       private final DisposeListener disposeListener = new DisposeListener() {
+               public void widgetDisposed(DisposeEvent e) {
+                       if (cursor != null) {
+                               cursor.dispose();
+                       }
+               }
+       };
+
+       
+       /**
+        * Changes the cursor to a cross-hair when mouse is over the image.
+        * 
+        */
+       private final MouseMoveListener cursorChanger = new MouseMoveListener() {
+
+               public void mouseMove(MouseEvent e) {
+                       Canvas canvas = view.getCanvas();
+                       if (view.imageContains(new Point(e.x, e.y))) {
+                               if (cursor == null) {
+                                       cursor = CursorFactory.createCrosshairCursor();
+                               }
+                               canvas.setCursor(cursor);
+                       } else {
+                               canvas.setCursor(getDisplay().getSystemCursor(SWT.CURSOR_ARROW));
+                       }
+               }
+       };
+
+
+       /**
+        * Listens for annotations and updates the buffer and view accordingly.
+        */
+       private final AnnotationListener listener = new AnnotationListener() {
+               
+               public void annotationUndone(AnnotationEvent e) {
+                       // Suspend notifications to prevent repainting the whole thing
+                       view.getImage().setSuspendNotifications(true);
+                       
+                       // Redraw all to buffer
+                       repaint();
+                       
+                       // Re-enable notifications
+                       view.getImage().setSuspendNotifications(false);
+                       
+                       // Repaint just the changed area
+                       view.getImage().fireImageChanged(e.annotation.getBounds());
+               }
+                       
+               
+               public void annotationsCleared(AnnotationEvent e) {
+                       // Repaint everything
+                       repaint();
+               }
+               
+               
+               public void annotationRedone(AnnotationEvent e) {       
+                       // Paint the new annotation
+                       e.annotation.paint(view.getImage());
+               }
+       
+               
+               public void annotationPerformed(AnnotationEvent e) {
+                       // Paint the new annotation
+                       e.annotation.paint(view.getImage());
+               }
+       };
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/widgets/BrushControl.java b/Annotation/src/ie/dcu/apps/ist/widgets/BrushControl.java
new file mode 100644 (file)
index 0000000..9459f79
--- /dev/null
@@ -0,0 +1,101 @@
+package ie.dcu.apps.ist.widgets;
+
+import ie.dcu.swt.PopupComposite;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+
+/**
+ * Pop up control for changing brush sizes.
+ * 
+ * @author Kevin McGuinness
+ */
+public class BrushControl extends PopupComposite {
+       private static final int MAX_BRUSH_SIZE = 20;
+
+       private final Label label;
+       private final Scale scale;
+       
+       
+       public BrushControl(Shell parent, int style) {
+               super(parent, style);
+               
+               // Create controls
+               label = new Label(this, SWT.NONE);
+               scale = new Scale(this, SWT.NONE);
+               
+               configureControls();
+               configureListeners();
+               layoutControls();
+       }
+
+
+       public void setBrushSize(int size) {
+               scale.setSelection(size);
+               updateLabel();
+       }
+       
+       
+       public int getBrushSize() {
+               return scale.getSelection();
+       }
+       
+       
+       public void addSelectionListener(SelectionListener listener) {
+               scale.addSelectionListener(listener);
+       }
+       
+       
+       public void removeSelectionListener(SelectionListener listener) {
+               scale.removeSelectionListener(listener);
+       }
+       
+       
+       private void configureControls() {
+               scale.setMinimum(1);
+               scale.setMaximum(MAX_BRUSH_SIZE);
+               scale.setIncrement(1);
+               scale.setPageIncrement(2);
+               setBrushSize(1);
+       }
+
+
+       private void configureListeners() {
+               scale.addSelectionListener(new ScaleChangeListener());
+       }
+
+
+       private void layoutControls() {
+               setLayout(new GridLayout());
+               
+               // Layout label
+               GridData gd = new GridData();
+               gd.grabExcessHorizontalSpace = true;
+               gd.horizontalAlignment = SWT.FILL;
+               label.setLayoutData(gd);
+               
+               // Layout scale control
+               gd = new GridData();
+               gd.grabExcessHorizontalSpace = true;
+               gd.horizontalAlignment = SWT.FILL;
+               gd.minimumWidth = 150;
+               scale.setLayoutData(gd);
+       }
+
+
+       private void updateLabel() {
+               int size = scale.getSelection();
+               label.setText(String.format("Brush Size:  %dpx ", size));
+       }
+
+
+       private final class ScaleChangeListener 
+               extends SelectionAdapter {
+               
+               public void widgetSelected(SelectionEvent e) {
+                       updateLabel();
+               }
+       };
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/widgets/ColorSelector.java b/Annotation/src/ie/dcu/apps/ist/widgets/ColorSelector.java
new file mode 100644 (file)
index 0000000..7efcf9d
--- /dev/null
@@ -0,0 +1,175 @@
+package ie.dcu.apps.ist.widgets;
+
+import java.beans.*;
+
+import org.eclipse.jface.resource.*;
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.widgets.*;
+
+/**
+ * Button for selecting colors.
+ * 
+ * @author Kevin McGuinness
+ */
+public class ColorSelector  {
+       public static final String DATA_KEY = "ColorEditor";
+       public static final String COLOR_PROPERTY = "color";
+
+       private final PropertyChangeSupport pcs;
+       private final Point extent;
+       private final Button button;
+       private final ControlListener listener;
+       
+       private Image image;
+       private RGB rgb;
+
+
+       public ColorSelector(Composite parent) {
+               
+               pcs = new PropertyChangeSupport(this);
+               button = new Button(parent, SWT.PUSH);
+               extent = computeImageSize(parent);
+               image = new Image(parent.getDisplay(), extent.x, extent.y);
+               listener = new ControlListener();
+
+               GC gc = new GC(image);
+               gc.setBackground(button.getBackground());
+               gc.fillRectangle(0, 0, extent.x, extent.y);
+               gc.dispose();
+
+               
+               button.setData(DATA_KEY, this);
+               button.setImage(image);
+               button.addListener(SWT.Selection, listener);
+               button.addListener(SWT.Dispose, listener);
+       }
+
+
+       public void addPropertyChangeListener(PropertyChangeListener listener) {
+               pcs.addPropertyChangeListener(listener);
+       }
+
+       
+       public void addPropertyChangeListener(String name, PropertyChangeListener listener) {
+               pcs.addPropertyChangeListener(name, listener);
+       }
+
+
+       public PropertyChangeListener[] getPropertyChangeListeners() {
+               return pcs.getPropertyChangeListeners();
+       }
+
+       
+       public PropertyChangeListener[] getPropertyChangeListeners(String name) {
+               return pcs.getPropertyChangeListeners(name);
+       }
+
+       
+       public void removePropertyChangeListener(PropertyChangeListener listener) {
+               pcs.removePropertyChangeListener(listener);
+       }
+
+
+       public void removePropertyChangeListener(String name, PropertyChangeListener listener) {
+               pcs.removePropertyChangeListener(name, listener);
+       }
+
+
+       public RGB getColor() {
+               return rgb;
+       }
+
+
+       public void setColor(RGB rgb) {
+               if (rgb != null && this.rgb != rgb) {
+                       RGB old = rgb;
+                       this.rgb = rgb;
+                       updateImage();
+                       pcs.firePropertyChange(COLOR_PROPERTY, old, rgb);
+               }
+       }
+       
+
+       public Button getButton() {
+               return button;
+       }
+
+
+       public void addListener(int eventType, Listener listener) {
+               button.addListener(eventType, listener);
+       }
+
+
+       public void setLayoutData(Object layoutData) {
+               button.setLayoutData(layoutData);
+       }
+       
+       
+       public void setData(Object data) {
+               button.setData(data);
+       }
+       
+       
+       public Object getData() {
+               return button.getData();
+       }
+
+
+       protected void updateImage() {
+               Display display = button.getDisplay();
+
+               GC gc = new GC(image);
+               gc.setForeground(display.getSystemColor(SWT.COLOR_BLACK));
+               gc.drawRectangle(0, 2, extent.x - 1, extent.y - 4);
+
+               Color color = new Color(display, rgb);
+               gc.setBackground(color);
+               gc.fillRectangle(1, 3, extent.x - 2, extent.y - 5);
+               gc.dispose();
+
+               button.setImage(image);
+               color.dispose();
+       }
+
+
+       protected Point computeImageSize(Composite parent) {
+               GC gc = new GC(parent);
+               Font f = JFaceResources.getFontRegistry().get(JFaceResources.DEFAULT_FONT);
+               gc.setFont(f);
+               int height = gc.getFontMetrics().getHeight();
+               gc.dispose();
+               Point p = new Point(height * 3 - 6, height);
+               return p;
+       }
+       
+       
+       private void handleDispose(Event e) {
+               if (image != null) {
+                       image.dispose();
+                       image = null;
+               }
+       }
+       
+       
+       private void handleSelection(Event e) {
+               ColorDialog dialog = new ColorDialog(button.getShell());
+               dialog.setRGB(rgb);
+               RGB rgb = dialog.open();
+               setColor(rgb);
+       }
+       
+       
+       private final class ControlListener implements Listener {
+               public void handleEvent(Event e) {
+                       switch (e.type) {
+                       case SWT.Selection:
+                               handleSelection(e);
+                               break;
+                       case SWT.Dispose:
+                               handleDispose(e);
+                               break;
+                       }
+               }
+       }
+}
\ No newline at end of file
diff --git a/Annotation/src/ie/dcu/apps/ist/widgets/ImageMenuManager.java b/Annotation/src/ie/dcu/apps/ist/widgets/ImageMenuManager.java
new file mode 100644 (file)
index 0000000..cfe0050
--- /dev/null
@@ -0,0 +1,54 @@
+package ie.dcu.apps.ist.widgets;
+
+import java.net.URL;
+
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+
+public class ImageMenuManager extends MenuManager {
+       private Image image;
+       
+       public ImageMenuManager() {
+               super();
+       }
+
+       public ImageMenuManager(String text) {
+               super(text);
+       }
+       
+       public ImageMenuManager(String text, URL imageURL) {
+               super(text);
+               setImageURL(imageURL);
+       }
+       
+       public void setImageURL(URL url) {
+               ImageDescriptor descriptor = ImageDescriptor.createFromURL(url);
+               this.image = descriptor.createImage();
+       }
+       
+       @Override
+       public void dispose() {
+               super.dispose();
+               
+               if (image != null) {
+                       image.dispose();
+               }
+       }       
+       
+       @Override
+       public void fill(Menu parent, int index) {
+               super.fill(parent, index);
+               MenuItem item = getMenuItem();
+               if (item != null) {
+                       item.setImage(image);
+               }
+       }
+
+       protected MenuItem getMenuItem() {
+               Menu menu = getMenu();
+               return (menu != null) ? menu.getParentItem() : null;
+       }
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/widgets/SwtTimer.java b/Annotation/src/ie/dcu/apps/ist/widgets/SwtTimer.java
new file mode 100644 (file)
index 0000000..6d1f97c
--- /dev/null
@@ -0,0 +1,642 @@
+package ie.dcu.apps.ist.widgets;
+
+
+import ie.dcu.apps.ist.event.*;
+
+import java.util.ArrayList;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.*;
+
+/**
+ * A timer user interface element. Displays a component used
+ * to implement a count-down.
+ * 
+ * @author Kevin McGuinness
+ */
+public class SwtTimer implements TickerListener {
+       
+       /**
+        * Timer is modeled as a state machine. These are the states.
+        */
+       public static enum State {      Initial, Ready, Running, Paused };
+       
+       
+       /**
+        * List of listeners interested in changes to the object state.
+        */
+       private final ArrayList<StateListener> stateListeners;
+       
+       
+       /**
+        * List of listeners interested in timeouts.
+        */
+       private final ArrayList<TimeoutListener> timeoutListeners;
+       
+       
+       /**
+        * The drawing canvas where the numbers are drawn.
+        */
+       private final Canvas canvas;
+       
+       
+       /**
+        * The ticker posts tick events every second or so.
+        */
+       private Ticker ticker;
+       
+       
+       /**
+        * The current state of the timer.
+        */
+       private State state;
+       
+       
+       /**
+        * The font used to render the numbers.
+        */
+       private Font font;
+       
+       
+       /**
+        * Total time for the timer, in seconds.
+        */
+       private int time;
+       
+       
+       /**
+        * Remaining (displayed) time, in seconds. 
+        */
+       private int remaining;
+       
+       
+       /**
+        * Create the timer. Style bits are passed to the underlying canvas.
+        * 
+        * @param parent
+        *          Parent container.
+        * @param style
+        *          Style bits.
+        */
+       public SwtTimer(Composite parent, int style) {
+               stateListeners = new ArrayList<StateListener>(1);
+               timeoutListeners = new ArrayList<TimeoutListener>(1);
+               canvas = new Canvas(parent, style);
+               addListeners();
+               enter(State.Initial);
+       }
+       
+       
+       /**
+        * Add listeners to various components.
+        */
+       private void addListeners() {
+               // Listen for paint events
+               canvas.addPaintListener(new PaintListener() {
+                       public void paintControl(PaintEvent e) {
+                               paint(e.gc);
+                       }
+               });
+               
+               // Listen for dispose event
+               canvas.addDisposeListener(new DisposeListener() {
+                       public void widgetDisposed(DisposeEvent e) {
+                               dispose();              
+                       }
+               });
+       }
+       
+       
+       /**
+        * Set the layout data for the component.
+        * 
+        * @param data
+        *          The layout data.
+        */
+       public void setLayoutData(Object data) {
+               canvas.setLayoutData(data);
+       }
+       
+       
+       /**
+        * Returns the layout data for the component.
+        * 
+        * @return The layout data.
+        */
+       public Object getLayoutData() {
+               return canvas.getLayoutData();
+       }
+       
+       
+       /**
+        * Get the contained canvas.
+        * 
+        * @return The contained canvas.
+        */
+       public Canvas getCanvas() {
+               return canvas;
+       }
+       
+       
+       /**
+        * Returns the shell associated with the canvas.
+        * 
+        * @return The shell.
+        */
+       public Shell getShell() {
+               return canvas.getShell();
+       }
+       
+       
+       /**
+        * Get the state of the timer.
+        * 
+        * @return The timer state.
+        */
+       public State getState() {
+               return state;
+       }
+       
+       
+       /**
+        * Add a state change listener.
+        * 
+        * @param listener
+        *          The listener.
+        */
+       public void addStateListener(StateListener listener) {
+               stateListeners.add(listener);
+       }
+       
+       
+       /**
+        * Remove a state change listener.
+        * 
+        * @param listener
+        *          The listener.
+        */
+       public void removeStateListener(StateListener listener) {
+               stateListeners.remove(listener);
+       }
+       
+       
+       /**
+        * Add a time-out listener.
+        * 
+        * @param listener
+        *          The listener.
+        */
+       public void addTimeoutListener(TimeoutListener listener) {
+               timeoutListeners.add(listener);
+       }
+       
+       
+       /**
+        * Remove a time-out listener.
+        * 
+        * @param listener
+        *          The listener.
+        */
+       public void removeTimeoutListener(TimeoutListener listener) {
+               timeoutListeners.remove(listener);
+       }
+       
+       
+       /**
+        * Returns an estimate of the elapsed time, in seconds.
+        * 
+        * @return The elapsed time.
+        */
+       public int getElapsed() {
+               return time - remaining;
+       }
+       
+       
+       /**
+        * Set the timeout for the timer, in seconds.
+        * 
+        * @param seconds
+        *          The number of seconds on the timer.
+        * @throws IllegalStateException
+        *          If {@link #canSet()} is <code>false</code>.
+        */
+       public void set(int seconds) throws IllegalStateException {
+               switch (state) {
+               case Initial:
+               case Ready:
+                       time = seconds;
+                       remaining = time;
+                       break;          
+               default:
+                       throw new IllegalStateException();
+               }
+               enter(State.Ready);
+               
+               repaint();
+       }
+       
+       
+       /**
+        * Returns <code>true</code> if set can be called. Set cannot be called when
+        * the timer is running or paused.
+        * 
+        * @return <code>true</code> if set can be called.
+        */
+       public boolean canSet() {
+               switch (state) {
+               case Initial:
+               case Ready:
+                       return true;
+               }
+               return false;
+       }
+       
+       
+       /**
+        * Start the timer. A new thread will control the timer count-down, so this
+        * method returns once it has started.
+        * 
+        * @throws IllegalStateException
+        *           If {@link #canStart()} is <code>false</code>.
+        */
+       public void start() throws IllegalStateException {
+               switch (state) {
+               case Ready:
+                       ticker = new Ticker(this, 1000);
+                       ticker.start();
+                       break;
+               case Paused:
+                       ticker.resume();
+                       break;
+               default:
+                       throw new IllegalStateException();
+               }
+               
+               enter(State.Running);
+               
+               repaint();
+       }
+       
+       
+       /**
+        * Returns <code>true</code> if start can be called. Start cannot be called
+        * when the timer is in it's initial or running state.
+        * 
+        * @return <code>true</code> if start can be called.
+        */
+       public boolean canStart() {
+               switch (state) {
+               case Ready:
+               case Paused:
+                       return true;
+               }
+               return false;
+       }
+       
+       
+       /**
+        * Pause the count-down. Temporarily suspends the count-down thread.
+        * 
+        * @throws IllegalStateException
+        *           If {@link #canPause()} is <code>false</code>.
+        */
+       public void pause() throws IllegalStateException {
+               switch (state) {
+               case Running:
+                       ticker.pause();
+                       break;
+               case Paused:
+                       break;
+               default:
+                       throw new IllegalStateException();
+               }
+               
+               enter(State.Paused);
+               
+               repaint();
+       }
+       
+       
+       /**
+        * Returns <code>true</code> if pause can be called. Pause cannot be called
+        * when the timer is in it's initial or ready state.
+        * 
+        * @return <code>true</code> if pause can be called.
+        */
+       public boolean canPause() {
+               switch (state) {
+               case Running:
+               case Paused:
+                       return true;
+               }
+               return false;
+       }
+       
+       
+       /**
+        * Reset the timer. Causes the timer to stop and return to the ready
+        * state, reseting the time-out to the last one set.
+        * 
+        * @throws IllegalStateException
+        *           If {@link #canReset()} is <code>false</code>.
+        */
+       public void reset() throws IllegalStateException {
+               switch (state) {
+               case Ready:
+                       break;
+               case Running:
+               case Paused:
+                       ticker.stop();
+                       ticker = null;
+                       remaining = time;
+                       break;
+               default:
+                       throw new IllegalStateException();
+               }
+               
+               enter(State.Ready);
+               
+               repaint();
+       }
+       
+       
+       /**
+        * Returns <code>true</code> if reset can be called. Reset cannot be called
+        * when the timer is in it's initial state.
+        * 
+        * @return <code>true</code> if reset can be called.
+        */
+       public boolean canReset() {
+               switch (state) {
+               case Ready:
+               case Running:
+               case Paused:
+                       return true;
+               }
+               return false;
+       }
+       
+       
+       /**
+        * Clear the timer. Returns the timer to its initial state, stopping
+        * it if necessary.
+        */
+       public void clear() {
+               switch (state) {
+               case Initial:
+                       break;
+               case Ready:
+                       time = 0;
+                       remaining = 0;
+                       break;
+               case Running:
+               case Paused:
+                       ticker.stop();
+                       ticker = null;
+                       remaining = 0;
+                       time = 0;
+                       break;
+               }
+               
+               enter(State.Initial);
+               
+               repaint();
+       }
+       
+       
+       /**
+        * Returns <code>true</code> if clear can be called.
+        * 
+        * @return Always returns <code>true</code>.
+        */
+       public boolean canClear() {
+               return true;
+       }
+       
+       
+       /**
+        * Tell the timer to repaint itself.
+        */
+       public void repaint() {
+               if (!canvas.isDisposed()) {
+                       canvas.redraw();
+               }
+       }
+       
+       
+       /**
+        * Called at each ticker tick interval. Should not be invoked by clients.
+        */
+       public void tick(final TickerEvent evt) {
+               if (canvas.isDisposed()) {
+                       // Widget is disposed, ignore timer events
+                       return;
+               }
+               
+               long elapsed = evt.getElapsed();
+               int remaining = time - (int) (elapsed / 1000); 
+               
+               if (remaining <= 0) {
+                       // We're done
+                       this.remaining = 0;
+                       
+                       // Stop and nullify ticker
+                       if (ticker != null) {
+                               ticker.stopLater();
+                               ticker = null;
+                       }
+                       
+                       // Enqueue the ui update the event dispatch thread
+                       canvas.getDisplay().asyncExec(new Runnable() {
+                               public void run() {
+                                       enter(State.Initial);
+                                       
+                                       // repaint
+                                       repaint();
+                                       
+                                       // fire timeout event
+                                       fireTimeoutEvent();
+                               }
+                       });
+               
+               } else if (this.remaining != remaining) {
+               
+                       // Update remaining 
+                       this.remaining = remaining;
+                       
+                       // Enqueue a repaint
+                       canvas.getDisplay().asyncExec(new Runnable() {
+                               public void run() {
+                                       // repaint
+                                       repaint();
+                               }
+                       });
+               }
+       }
+       
+       
+       /**
+        * Enter the given state.
+        * 
+        * @param state The state.
+        */
+       private void enter(State state) {
+               if (this.state != state) {
+                       this.state = state;
+                       fireStateChanged();
+               }
+       }
+       
+       
+       /**
+        * Fires a state changed event.
+        */
+       private void fireStateChanged() {
+               if (!stateListeners.isEmpty()) {
+                       StateEvent evt = new StateEvent(this);
+                       for (StateListener s : stateListeners) {
+                               s.stateChanged(evt);
+                       }
+               }
+       }
+
+
+       /**
+        * Sends a timeout event to listeners.
+        */
+       private void fireTimeoutEvent() {
+               if (!timeoutListeners.isEmpty()) {
+                       TimeoutEvent evt = new TimeoutEvent(this);
+                       for (TimeoutListener t : timeoutListeners) {
+                               t.timeoutOccured(evt);
+                       }
+               }
+       }
+       
+       
+       /**
+        * Paints the timer.
+        * 
+        * @param gc
+        *          The graphics context.
+        */
+       private void paint(GC gc) {
+               gc.setFont(getTimerFont());
+               
+               int ss = remaining % 60;
+               int mm = (remaining % 3600) / 60;
+               int hh = remaining / 3600;
+               
+               String timestr = formatTime(ss, mm, hh);
+               
+               Point t = getStringDimensions(gc, timestr);
+               Point c = getCanvasDimension();
+               
+               int x = c.x / 2 - t.x / 2;
+               int y = c.y / 2 - t.y / 2;
+               
+               if (remaining < 20 && state != State.Initial) {
+                       gc.setForeground(getWarningColor());
+               } else {
+                       gc.setForeground(getTimerColor());
+               }
+               
+               gc.drawString(timestr, x, y);
+       }
+       
+
+       /**
+        * Tidies native resources. Called automatically.
+        */
+       private void dispose() {
+               if (font != null) {
+                       font.dispose();
+                       font = null;
+               }
+       }
+       
+       
+       /**
+        * Formats a time string.
+        */
+       private String formatTime(int ss, int mm, int hh) {
+               String timestr;
+               if (hh == 0) {
+                       timestr = String.format("%02d:%02d", mm, ss);
+               } else {
+                       timestr = String.format("%02d:%02d:%02d", hh, mm, ss);
+               }
+               return timestr;
+       }
+       
+       
+       /**
+        * Returns the dimensions of a given string as drawn with the current font on
+        * the given graphics context.
+        */
+       private static Point getStringDimensions(GC gc, String str) {
+               int x = 0;
+               for (int i = 0; i < str.length(); i++) {
+                       x += gc.getAdvanceWidth(str.charAt(i));
+               }
+               int y = gc.getFontMetrics().getHeight();
+               return new Point(x,y);
+       }
+       
+       
+       /**
+        * Returns the dimensions of the canvas as a point.
+        * 
+        * @return A point where x is the width and y is the height.
+        */
+       private Point getCanvasDimension() {
+               Rectangle bounds = canvas.getBounds();
+               return new Point(bounds.width, bounds.height);
+       }
+       
+
+       private Color getWarningColor() {
+               return getSystemColor(SWT.COLOR_RED);
+       }
+       
+       
+       private Color getTimerColor() {
+               return getSystemColor(SWT.COLOR_DARK_BLUE);
+       }
+       
+       
+       private Font getTimerFont() {
+               if (font == null) {
+                       font = new Font(canvas.getDisplay(), "Sans", 30, SWT.NONE);
+               }
+               return font;
+       }
+       
+       
+       private Color getSystemColor(int id) {
+               return canvas.getDisplay().getSystemColor(id);
+       }
+
+       public static void main(String[] args) {
+               Display display = new Display();
+               Shell shell = new Shell(display, SWT.SHELL_TRIM);
+               shell.setBounds(800, 100, 220, 200);
+               shell.setLayout(new FillLayout());
+               
+               SwtTimer timer = new SwtTimer(shell, SWT.NONE);
+               timer.set(120);
+               timer.start();
+               
+               shell.open();
+               while (!shell.isDisposed()) {
+                       if (!display.readAndDispatch()) {
+                               display.sleep();
+                       }
+               }
+               display.dispose();
+       }
+       
+}
diff --git a/Annotation/src/ie/dcu/apps/ist/widgets/Ticker.java b/Annotation/src/ie/dcu/apps/ist/widgets/Ticker.java
new file mode 100644 (file)
index 0000000..c2d48ab
--- /dev/null
@@ -0,0 +1,246 @@
+package ie.dcu.apps.ist.widgets;
+
+import ie.dcu.apps.ist.event.*;
+
+
+public class Ticker implements Runnable {
+       private final TickerListener listener;
+       
+       private Thread thread   = null;
+       private boolean pause   = false;
+       private boolean stop    = false; 
+       private long napTime    = 100;
+       private long interval   = 1000;
+       private long elapsed    = 0;
+       private long startTime  = 0;
+       private long pausedTime = 0;
+       
+       // State variables
+       private boolean paused  = false;
+       private boolean stopped = true;
+       
+       public Ticker(TickerListener listener) {
+               
+               // Check listener
+               if (listener == null) {
+                       throw new IllegalArgumentException();
+               }
+               
+               this.listener = listener;
+       }
+       
+       
+       public Ticker(TickerListener listener, long interval) {
+               
+               // Check listener
+               if (listener == null) {
+                       throw new IllegalArgumentException();
+               }
+               
+               // Check interval
+               if (interval < 0) {
+                       throw new IllegalArgumentException();
+               }
+               
+               // Assign
+               this.listener = listener;
+               this.interval = interval;
+               this.napTime  = interval / 10;
+       }
+       
+       
+       public synchronized long elapsed() {
+               return elapsed;
+       }
+       
+       
+       public void start() {
+               if (thread != null) {
+                       throw new IllegalStateException("Cannot restart threads");
+               }
+               thread = new Thread(this, "TimerThread");
+               thread.start();
+       }
+       
+       
+       public void run() {
+               
+               synchronized (this) {
+                       stopped = false;
+               }
+               
+               // Set start time
+               startTime = System.currentTimeMillis();
+               
+               // Loop
+               while (true) {
+                       
+                       // Yawn! Z Z z z z Z Z Z z z z Z Z Z ...
+                       sleep(napTime);
+                       
+                       // Wait while thread is paused
+                       synchronized (this) {
+                               if (pause) {
+                                       
+                                       // Remember when pausing started
+                                       long now = System.currentTimeMillis();
+                                       
+                                       // Set paused flag to true and notify
+                                       paused = true;
+                                       notifyAll();
+                                       
+                                       // Wait until woken up
+                                       while (paused) doWait();
+                                       
+                                       // Add duration we've been paused for
+                                       pausedTime += System.currentTimeMillis() - now;
+                                       
+                                       // Clear pause flag && notify
+                                       pause = false;
+                                       notifyAll();
+                               }
+                       }
+                       
+                       // Check for stop flag
+                       synchronized (this) {
+                               if (stop) {
+                                       stopped = true;
+                                       notifyAll();
+                                       break;
+                               }
+                       }
+                       
+                       // HI-HO-HI-HO ...
+                       
+                       work();
+               }
+       }
+       
+       
+       private void work() { 
+               boolean event = false;
+               
+               synchronized (this) {
+                       // Calculate total elapsed time in milliseconds
+                       long now = System.currentTimeMillis();
+                       long elapsed = now - (startTime + pausedTime); 
+                       
+                       // Calculate time elapsed since last event
+                       long sinceLast = elapsed - this.elapsed;
+                       if (interval <= sinceLast) {
+                               
+                               // Compensate for any difference
+                               long diff = sinceLast - interval;
+                               
+                               // Its time for another event
+                               this.elapsed = elapsed - diff;
+                               
+                               // Fire event flag
+                               event = true;
+                       }
+               }
+               
+               // Do event
+               if (event) {
+                       synchronized (listener) {
+                               listener.tick(new TickerEvent(this, elapsed));
+                       }
+               }
+       }
+
+
+       public void pause() {
+               // Pause running thread
+               synchronized (this) {
+                       pause = true;
+                       
+                       // Wait for pause to occur
+                       while (!paused) doWait();
+               }
+       }
+       
+       
+       public void resume() {
+               // Wake up paused threads
+               synchronized (this) {
+                       if (paused) {
+                               paused = false;
+                               notifyAll();
+                       }
+                       
+                       while (pause) doWait();
+               }
+       }
+       
+       
+       public boolean isPaused() {
+               synchronized (this) {
+                       return paused;
+               }
+       }
+       
+       
+       public void stop() {
+               
+               synchronized (this) {
+                       
+                       // Resume paused threads
+                       if (paused) {
+                               paused = false;
+                               notifyAll();
+                       }
+                       
+                       while (pause) doWait();
+                       
+                       // Stop
+                       stop = true;
+                       
+                       // Wait until stop block reached
+                       while (!stopped) doWait();
+               }
+       }
+       
+       
+       public void stopLater() {
+               synchronized (this) {
+                       
+                       // Resume paused threads
+                       if (paused) {
+                               paused = false;
+                               notifyAll();
+                       }
+                       
+                       while (pause) doWait();
+                       
+                       // Stop
+                       stop = true;
+               }
+       }
+       
+       
+       public boolean isStopped() {
+               synchronized (this) {
+                       return stopped;
+               }
+       }
+       
+       
+       private void sleep(long millis) {
+               try {
+                       Thread.sleep(millis);
+               } catch (InterruptedException e) {
+                       // Ignore
+               }
+       }
+       
+       
+       private void doWait() {
+               try {
+                       wait();
+               } catch (InterruptedException e) {
+                       // ignore
+               }
+       }
+}
+
+
diff --git a/Annotation/src/ie/dcu/array/Arrays.class b/Annotation/src/ie/dcu/array/Arrays.class
new file mode 100644 (file)
index 0000000..767b525
Binary files /dev/null and b/Annotation/src/ie/dcu/array/Arrays.class differ
diff --git a/Annotation/src/ie/dcu/array/Arrays.java b/Annotation/src/ie/dcu/array/Arrays.java
new file mode 100644 (file)
index 0000000..755c087
--- /dev/null
@@ -0,0 +1,3233 @@
+package ie.dcu.array;
+
+import java.lang.reflect.Array;
+
+/**
+ * Collection of static methods on arrays.
+ * 
+ * @author Kevin McGuinness
+ */
+public class Arrays  {
+       
+       /**
+        * Clamp the values in the given byte matrix to the given range.
+        * 
+        * The values array is modified (if necessary).
+        * 
+        * The passed array must be one of the following types: 
+        * <ul>
+        *   <li><code>byte[]</code></li>
+        *   <li><code>short[]</code></li>
+        *   <li><code>int[]</code></li>
+        *   <li><code>long[]</code></li>
+        *   <li><code>float[]</code></li>
+        *   <li><code>double[]</code></li>
+        * </ul>
+        * 
+        * @param array
+        *        An array.
+        * @param min
+        *            The minimum value.
+        * @param max
+        *            The maximum value.
+        * @return 
+        *        The modified input matrix.
+        * @throws UnsupportedOperationException
+        *        If the passed array is not one of the supported types.
+        */
+       public static Object clamp(Object array, Number min, Number max) 
+               throws UnsupportedOperationException 
+       {       
+               if (array instanceof byte[]) {
+                       return clamp((byte[]) array, min.byteValue(), max.byteValue());
+               } else if (array instanceof short[]) {
+                       return clamp((short[]) array, min.shortValue(), max.shortValue());
+               } else if (array instanceof int[]) {
+                       return clamp((int[]) array, min.intValue(), max.intValue());
+               } else if (array instanceof long[]) {
+                       return clamp((long[]) array, min.longValue(), max.longValue());
+               } else if (array instanceof float[]) {
+                       return clamp((float[]) array, min.longValue(), max.longValue());
+               } else if (array instanceof double[]) {
+                       return clamp((double[]) array, min.longValue(), max.longValue());
+               } else {
+                       throw new UnsupportedOperationException();
+               }
+       }       
+
+       /**
+        * Clamp the values in the given byte matrix to the given range.
+        * 
+        * The values array is modified (if necessary).
+        *
+        * @param values
+        *            A matrix of byte values.
+        * @param min
+        *            The minimum value.
+        * @param max
+        *            The maximum value.
+        * @return The modified input matrix.
+        */
+       public static byte[] clamp(byte[] values, byte min, byte max) {
+               if (min > max) {
+                       throw new IllegalArgumentException("min > max");
+               }
+               
+               for (int i = 0; i < values.length; i++) {
+                       if (values[i] < min) {
+                               values[i] = min;
+                       }
+                       
+                       if (values[i] > max) {
+                               values[i] = max;
+                       }
+               }
+               
+               return values;
+       }
+
+       /**
+        * Clamp the values in the given short matrix to the given range.
+        * 
+        * The values array is modified (if necessary).
+        *
+        * @param values
+        *            A matrix of short values.
+        * @param min
+        *            The minimum value.
+        * @param max
+        *            The maximum value.
+        * @return The modified input matrix.
+        */
+       public static short[] clamp(short[] values, short min, short max) {
+               if (min > max) {
+                       throw new IllegalArgumentException("min > max");
+               }
+               
+               for (int i = 0; i < values.length; i++) {
+                       if (values[i] < min) {
+                               values[i] = min;
+                       }
+                       
+                       if (values[i] > max) {
+                               values[i] = max;
+                       }
+               }
+               
+               return values;
+       }
+
+       /**
+        * Clamp the values in the given int matrix to the given range.
+        * 
+        * The values array is modified (if necessary).
+        *
+        * @param values
+        *            A matrix of int values.
+        * @param min
+        *            The minimum value.
+        * @param max
+        *            The maximum value.
+        * @return The modified input matrix.
+        */
+       public static int[] clamp(int[] values, int min, int max) {
+               if (min > max) {
+                       throw new IllegalArgumentException("min > max");
+               }
+               
+               for (int i = 0; i < values.length; i++) {
+                       if (values[i] < min) {
+                               values[i] = min;
+                       }
+                       
+                       if (values[i] > max) {
+                               values[i] = max;
+                       }
+               }
+               
+               return values;
+       }
+
+       /**
+        * Clamp the values in the given long matrix to the given range.
+        * 
+        * The values array is modified (if necessary).
+        *
+        * @param values
+        *            A matrix of long values.
+        * @param min
+        *            The minimum value.
+        * @param max
+        *            The maximum value.
+        * @return The modified input matrix.
+        */
+       public static long[] clamp(long[] values, long min, long max) {
+               if (min > max) {
+                       throw new IllegalArgumentException("min > max");
+               }
+               
+               for (int i = 0; i < values.length; i++) {
+                       if (values[i] < min) {
+                               values[i] = min;
+                       }
+                       
+                       if (values[i] > max) {
+                               values[i] = max;
+                       }
+               }
+               
+               return values;
+       }
+
+       /**
+        * Clamp the values in the given float matrix to the given range.
+        * 
+        * The values array is modified (if necessary).
+        *
+        * @param values
+        *            A matrix of float values.
+        * @param min
+        *            The minimum value.
+        * @param max
+        *            The maximum value.
+        * @return The modified input matrix.
+        */
+       public static float[] clamp(float[] values, float min, float max) {
+               if (min > max) {
+                       throw new IllegalArgumentException("min > max");
+               }
+               
+               for (int i = 0; i < values.length; i++) {
+                       if (values[i] < min) {
+                               values[i] = min;
+                       }
+                       
+                       if (values[i] > max) {
+                               values[i] = max;
+                       }
+               }
+               
+               return values;
+       }
+
+       /**
+        * Clamp the values in the given double matrix to the given range.
+        * 
+        * The values array is modified (if necessary).
+        *
+        * @param values
+        *            A matrix of double values.
+        * @param min
+        *            The minimum value.
+        * @param max
+        *            The maximum value.
+        * @return The modified input matrix.
+        */
+       public static double[] clamp(double[] values, double min, double max) {
+               if (min > max) {
+                       throw new IllegalArgumentException("min > max");
+               }
+               
+               for (int i = 0; i < values.length; i++) {
+                       if (values[i] < min) {
+                               values[i] = min;
+                       }
+                       
+                       if (values[i] > max) {
+                               values[i] = max;
+                       }
+               }
+               
+               return values;
+       }
+       
+       /**
+        * Filter the values in the given array.
+        * 
+        * @param array
+        *        An array.
+        * @param filter
+        *        A filter.
+        * @return
+        *        The filtered array.
+        */
+       @SuppressWarnings("unchecked")
+       public static <T> T[] filter(T[] array, Filter filter) {
+               T[] buffer = (T[]) Array.newInstance(
+                               array.getClass().getComponentType(), array.length);
+               
+               int count = 0;
+               for (int i = 0; i < array.length; i++) {
+                       if (filter.retain(array[i])) {
+                               buffer[count++] = array[i];
+                       }
+               }
+               
+               return subarray(buffer, 0, count);
+       }
+       
+
+       /**
+        * Filter the values in the given byte array.
+        *
+        * This method is potentially more efficient than the generic Filter 
+        * version, since it must box each value in the array.
+        * 
+        * @param array
+        *        An array of bytes.
+        * @param filter
+        *        A filter.
+        * @return
+        *        The filtered array.
+        */
+       public static byte[] filter(byte[] array, Filter.Byte filter) {
+               byte[] buffer = new byte[array.length];
+               
+               int count = 0;
+               for (int i = 0; i < array.length; i++) {
+                       if (filter.retain(array[i])) {
+                               buffer[count++] = array[i];
+                       }
+               }
+               
+               return subarray(buffer, 0, count);
+       }
+
+       /**
+        * Filter the values in the given byte array.
+        * 
+        * @param array
+        *        An array of bytes.
+        * @param filter
+        *        A filter.
+        * @return
+        *        The filtered array.
+        */
+       public static byte[] filter(byte[] array, Filter filter) {
+               byte[] buffer = new byte[array.length];
+               
+               int count = 0;
+               for (int i = 0; i < array.length; i++) {
+                       if (filter.retain(array[i])) {
+                               buffer[count++] = array[i];
+                       }
+               }
+               
+               return subarray(buffer, 0, count);
+       }
+
+       /**
+        * Filter the values in the given short array.
+        *
+        * This method is potentially more efficient than the generic Filter 
+        * version, since it must box each value in the array.
+        * 
+        * @param array
+        *        An array of shorts.
+        * @param filter
+        *        A filter.
+        * @return
+        *        The filtered array.
+        */
+       public static short[] filter(short[] array, Filter.Short filter) {
+               short[] buffer = new short[array.length];
+               
+               int count = 0;
+               for (int i = 0; i < array.length; i++) {
+                       if (filter.retain(array[i])) {
+                               buffer[count++] = array[i];
+                       }
+               }
+               
+               return subarray(buffer, 0, count);
+       }
+
+       /**
+        * Filter the values in the given short array.
+        * 
+        * @param array
+        *        An array of shorts.
+        * @param filter
+        *        A filter.
+        * @return
+        *        The filtered array.
+        */
+       public static short[] filter(short[] array, Filter filter) {
+               short[] buffer = new short[array.length];
+               
+               int count = 0;
+               for (int i = 0; i < array.length; i++) {
+                       if (filter.retain(array[i])) {
+                               buffer[count++] = array[i];
+                       }
+               }
+               
+               return subarray(buffer, 0, count);
+       }
+
+       /**
+        * Filter the values in the given int array.
+        *
+        * This method is potentially more efficient than the generic Filter 
+        * version, since it must box each value in the array.
+        * 
+        * @param array
+        *        An array of ints.
+        * @param filter
+        *        A filter.
+        * @return
+        *        The filtered array.
+        */
+       public static int[] filter(int[] array, Filter.Integer filter) {
+               int[] buffer = new int[array.length];
+               
+               int count = 0;
+               for (int i = 0; i < array.length; i++) {
+                       if (filter.retain(array[i])) {
+                               buffer[count++] = array[i];
+                       }
+               }
+               
+               return subarray(buffer, 0, count);
+       }
+
+       /**
+        * Filter the values in the given int array.
+        * 
+        * @param array
+        *        An array of ints.
+        * @param filter
+        *        A filter.
+        * @return
+        *        The filtered array.
+        */
+       public static int[] filter(int[] array, Filter filter) {
+               int[] buffer = new int[array.length];
+               
+               int count = 0;
+               for (int i = 0; i < array.length; i++) {
+                       if (filter.retain(array[i])) {
+                               buffer[count++] = array[i];
+                       }
+               }
+               
+               return subarray(buffer, 0, count);
+       }
+
+       /**
+        * Filter the values in the given long array.
+        *
+        * This method is potentially more efficient than the generic Filter 
+        * version, since it must box each value in the array.
+        * 
+        * @param array
+        *        An array of longs.
+        * @param filter
+        *        A filter.
+        * @return
+        *        The filtered array.
+        */
+       public static long[] filter(long[] array, Filter.Long filter) {
+               long[] buffer = new long[array.length];
+               
+               int count = 0;
+               for (int i = 0; i < array.length; i++) {
+                       if (filter.retain(array[i])) {
+                               buffer[count++] = array[i];
+                       }
+               }
+               
+               return subarray(buffer, 0, count);
+       }
+
+       /**
+        * Filter the values in the given long array.
+        * 
+        * @param array
+        *        An array of longs.
+        * @param filter
+        *        A filter.
+        * @return
+        *        The filtered array.
+        */
+       public static long[] filter(long[] array, Filter filter) {
+               long[] buffer = new long[array.length];
+               
+               int count = 0;
+               for (int i = 0; i < array.length; i++) {
+                       if (filter.retain(array[i])) {
+                               buffer[count++] = array[i];
+                       }
+               }
+               
+               return subarray(buffer, 0, count);
+       }
+
+       /**
+        * Filter the values in the given float array.
+        *
+        * This method is potentially more efficient than the generic Filter 
+        * version, since it must box each value in the array.
+        * 
+        * @param array
+        *        An array of floats.
+        * @param filter
+        *        A filter.
+        * @return
+        *        The filtered array.
+        */
+       public static float[] filter(float[] array, Filter.Float filter) {
+               float[] buffer = new float[array.length];
+               
+               int count = 0;
+               for (int i = 0; i < array.length; i++) {
+                       if (filter.retain(array[i])) {
+                               buffer[count++] = array[i];
+                       }
+               }
+               
+               return subarray(buffer, 0, count);
+       }
+
+       /**
+        * Filter the values in the given float array.
+        * 
+        * @param array
+        *        An array of floats.
+        * @param filter
+        *        A filter.
+        * @return
+        *        The filtered array.
+        */
+       public static float[] filter(float[] array, Filter filter) {
+               float[] buffer = new float[array.length];
+               
+               int count = 0;
+               for (int i = 0; i < array.length; i++) {
+                       if (filter.retain(array[i])) {
+                               buffer[count++] = array[i];
+                       }
+               }
+               
+               return subarray(buffer, 0, count);
+       }
+
+       /**
+        * Filter the values in the given double array.
+        *
+        * This method is potentially more efficient than the generic Filter 
+        * version, since it must box each value in the array.
+        * 
+        * @param array
+        *        An array of doubles.
+        * @param filter
+        *        A filter.
+        * @return
+        *        The filtered array.
+        */
+       public static double[] filter(double[] array, Filter.Double filter) {
+               double[] buffer = new double[array.length];
+               
+               int count = 0;
+               for (int i = 0; i < array.length; i++) {
+                       if (filter.retain(array[i])) {
+                               buffer[count++] = array[i];
+                       }
+               }
+               
+               return subarray(buffer, 0, count);
+       }
+
+       /**
+        * Filter the values in the given double array.
+        * 
+        * @param array
+        *        An array of doubles.
+        * @param filter
+        *        A filter.
+        * @return
+        *        The filtered array.
+        */
+       public static double[] filter(double[] array, Filter filter) {
+               double[] buffer = new double[array.length];
+               
+               int count = 0;
+               for (int i = 0; i < array.length; i++) {
+                       if (filter.retain(array[i])) {
+                               buffer[count++] = array[i];
+                       }
+               }
+               
+               return subarray(buffer, 0, count);
+       }
+       
+       /**
+        * Returns a sub-array of the given array.
+        * 
+        * @param array
+        *        The array of bytes.
+        * @param startPos
+        *        The start position.
+        * @param count
+        *        The number of elements.
+        * @return
+        *        The sub-array.
+        * @throws IndexOutOfBoundsException
+        *        If the operation would result in an index out of bounds
+        *        error.
+        */
+       @SuppressWarnings("unchecked")
+       public static <T> T[] subarray(T[] array, int startPos, int count) {
+               checkSubarray(array.length, startPos, count);
+               T[] result = (T[]) Array.newInstance(
+                               array.getClass().getComponentType(), count);
+               System.arraycopy(array, 0, result, 0, count);
+               return result;
+       }
+       
+       /**
+        * Returns a sub-array of the given array.
+        * 
+        * @param array
+        *        The array of bytes.
+        * @param startPos
+        *        The start position.
+        * @param count
+        *        The number of elements.
+        * @return
+        *        The sub-array.
+        * @throws IndexOutOfBoundsException
+        *        If the operation would result in an index out of bounds
+        *        error.
+        */
+       public static byte[] subarray(byte[] array, int startPos, int count) {
+               checkSubarray(array.length, startPos, count);
+               byte[] result = new byte[count];
+               System.arraycopy(array, 0, result, 0, count);
+               return result;
+       }
+
+       /**
+        * Returns a sub-array of the given array.
+        * 
+        * @param array
+        *        The array of shorts.
+        * @param startPos
+        *        The start position.
+        * @param count
+        *        The number of elements.
+        * @return
+        *        The sub-array.
+        * @throws IndexOutOfBoundsException
+        *        If the operation would result in an index out of bounds
+        *        error.
+        */
+       public static short[] subarray(short[] array, int startPos, int count) {
+               checkSubarray(array.length, startPos, count);
+               short[] result = new short[count];
+               System.arraycopy(array, 0, result, 0, count);
+               return result;
+       }
+
+       /**
+        * Returns a sub-array of the given array.
+        * 
+        * @param array
+        *        The array of ints.
+        * @param startPos
+        *        The start position.
+        * @param count
+        *        The number of elements.
+        * @return
+        *        The sub-array.
+        * @throws IndexOutOfBoundsException
+        *        If the operation would result in an index out of bounds
+        *        error.
+        */
+       public static int[] subarray(int[] array, int startPos, int count) {
+               checkSubarray(array.length, startPos, count);
+               int[] result = new int[count];
+               System.arraycopy(array, 0, result, 0, count);
+               return result;
+       }
+
+       /**
+        * Returns a sub-array of the given array.
+        * 
+        * @param array
+        *        The array of longs.
+        * @param startPos
+        *        The start position.
+        * @param count
+        *        The number of elements.
+        * @return
+        *        The sub-array.
+        * @throws IndexOutOfBoundsException
+        *        If the operation would result in an index out of bounds
+        *        error.
+        */
+       public static long[] subarray(long[] array, int startPos, int count) {
+               checkSubarray(array.length, startPos, count);
+               long[] result = new long[count];
+               System.arraycopy(array, 0, result, 0, count);
+               return result;
+       }
+
+       /**
+        * Returns a sub-array of the given array.
+        * 
+        * @param array
+        *        The array of floats.
+        * @param startPos
+        *        The start position.
+        * @param count
+        *        The number of elements.
+        * @return
+        *        The sub-array.
+        * @throws IndexOutOfBoundsException
+        *        If the operation would result in an index out of bounds
+        *        error.
+        */
+       public static float[] subarray(float[] array, int startPos, int count) {
+               checkSubarray(array.length, startPos, count);
+               float[] result = new float[count];
+               System.arraycopy(array, 0, result, 0, count);
+               return result;
+       }
+
+       /**
+        * Returns a sub-array of the given array.
+        * 
+        * @param array
+        *        The array of doubles.
+        * @param startPos
+        *        The start position.
+        * @param count
+        *        The number of elements.
+        * @return
+        *        The sub-array.
+        * @throws IndexOutOfBoundsException
+        *        If the operation would result in an index out of bounds
+        *        error.
+        */
+       public static double[] subarray(double[] array, int startPos, int count) {
+               checkSubarray(array.length, startPos, count);
+               double[] result = new double[count];
+               System.arraycopy(array, 0, result, 0, count);
+               return result;
+       }
+       
+       /**
+        * Check if the subarray operation will result in an 
+        * {@link IndexOutOfBoundsException}
+        */
+       private static void checkSubarray(int length, int startPos, int count) {
+               if (startPos < 0) {
+                       throw new IndexOutOfBoundsException("startPos < 0");
+               }
+               
+               if (count < 0) {
+                       throw new IndexOutOfBoundsException("count < 0");
+               }
+               
+               if (startPos + count > length) {
+                       throw new IndexOutOfBoundsException("startPos + count > array.length");
+               }
+       }
+       
+       /**
+        * Perform a reduction on the given array of bytes.
+        * 
+        * @param array 
+        *        An array.
+        * @param initialValue 
+        *        The initial value for the reduction.
+        * @param operation
+        *        The reduction operation.
+        * @return
+        *        The result of the reduction.
+        */
+       public static <T, U> U reduce(T[] array, U initialValue, 
+                       Reduction<T,U> operation) 
+       {
+               U accumulator = initialValue;
+               for (int i = 0; i < array.length; i++) {
+                       accumulator = operation.reduce(accumulator, array[i], i);
+               }
+               return accumulator;
+       }
+
+       /**
+        * Perform a reduction on the given array of bytes.
+        * 
+        * @param array 
+        *        An array of bytes.
+        * @param initialValue 
+        *        The initial value for the reduction.
+        * @param operation
+        *        The reduction operation.
+        * @return
+        *        The result of the reduction.
+        */
+       public static long reduce(byte[] array, long initialValue, 
+                       Reduction.Long operation) 
+       {
+               long accumulator = initialValue;
+               for (int i = 0; i < array.length; i++) {
+                       accumulator = operation.reduce(accumulator, array[i], i);
+               }
+               return accumulator;
+       }
+
+       /**
+        * Perform a reduction on the given array of shorts.
+        * 
+        * @param array 
+        *        An array of shorts.
+        * @param initialValue 
+        *        The initial value for the reduction.
+        * @param operation
+        *        The reduction operation.
+        * @return
+        *        The result of the reduction.
+        */
+       public static long reduce(short[] array, long initialValue, 
+                       Reduction.Long operation) 
+       {
+               long accumulator = initialValue;
+               for (int i = 0; i < array.length; i++) {
+                       accumulator = operation.reduce(accumulator, array[i], i);
+               }
+               return accumulator;
+       }
+
+       /**
+        * Perform a reduction on the given array of ints.
+        * 
+        * @param array 
+        *        An array of ints.
+        * @param initialValue 
+        *        The initial value for the reduction.
+        * @param operation
+        *        The reduction operation.
+        * @return
+        *        The result of the reduction.
+        */
+       public static long reduce(int[] array, long initialValue, 
+                       Reduction.Long operation) 
+       {
+               long accumulator = initialValue;
+               for (int i = 0; i < array.length; i++) {
+                       accumulator = operation.reduce(accumulator, array[i], i);
+               }
+               return accumulator;
+       }
+
+       /**
+        * Perform a reduction on the given array of longs.
+        * 
+        * @param array 
+        *        An array of longs.
+        * @param initialValue 
+        *        The initial value for the reduction.
+        * @param operation
+        *        The reduction operation.
+        * @return
+        *        The result of the reduction.
+        */
+       public static long reduce(long[] array, long initialValue, 
+                       Reduction.Long operation) 
+       {
+               long accumulator = initialValue;
+               for (int i = 0; i < array.length; i++) {
+                       accumulator = operation.reduce(accumulator, array[i], i);
+               }
+               return accumulator;
+       }
+
+       /**
+        * Perform a reduction on the given array of floats.
+        * 
+        * @param array 
+        *        An array of floats.
+        * @param initialValue 
+        *        The initial value for the reduction.
+        * @param operation
+        *        The reduction operation.
+        * @return
+        *        The result of the reduction.
+        */
+       public static double reduce(float[] array, double initialValue, 
+                       Reduction.Double operation) 
+       {
+               double accumulator = initialValue;
+               for (int i = 0; i < array.length; i++) {
+                       accumulator = operation.reduce(accumulator, array[i], i);
+               }
+               return accumulator;
+       }
+
+       /**
+        * Perform a reduction on the given array of doubles.
+        * 
+        * @param array 
+        *        An array of doubles.
+        * @param initialValue 
+        *        The initial value for the reduction.
+        * @param operation
+        *        The reduction operation.
+        * @return
+        *        The result of the reduction.
+        */
+       public static double reduce(double[] array, double initialValue, 
+                       Reduction.Double operation) 
+       {
+               double accumulator = initialValue;
+               for (int i = 0; i < array.length; i++) {
+                       accumulator = operation.reduce(accumulator, array[i], i);
+               }
+               return accumulator;
+       }
+       
+       /**
+        * Finds the sum of all elements in the given array.
+        * 
+        * The passed array must be one of the following types: 
+        * <ul>
+        *   <li><code>byte[]</code></li>
+        *   <li><code>short[]</code></li>
+        *   <li><code>int[]</code></li>
+        *   <li><code>long[]</code></li>
+        *   <li><code>float[]</code></li>
+        *   <li><code>double[]</code></li>
+        * </ul>
+        * 
+        * @param array
+        *        An array.
+        * @return 
+        *        The sum of all elements in the given array as a Number.
+        * @throws UnsupportedOperationException
+        *        If the passed array is not one of the supported types.
+        */
+       public static Number sum(Object array) 
+               throws UnsupportedOperationException 
+       {       
+               if (array instanceof byte[]) {
+                       return sum((byte[]) array);
+               } else if (array instanceof short[]) {
+                       return sum((short[]) array);
+               } else if (array instanceof int[]) {
+                       return sum((int[]) array);
+               } else if (array instanceof long[]) {
+                       return sum((long[]) array);
+               } else if (array instanceof float[]) {
+                       return sum((float[]) array);
+               } else if (array instanceof double[]) {
+                       return sum((double[]) array);
+               } else {
+                       throw new UnsupportedOperationException();
+               }
+       }
+
+       /**
+        * Computes the sum of all the elements in the given byte array.
+        * 
+        * @param array
+        *        An array of bytes.
+        * @return
+        *        The sum of all elements in the array.
+        */
+       public static long sum(byte[] array) {
+               long sumValue = 0;
+               for (int i = 0; i < array.length; i++) {
+                       sumValue += array[i];
+               }
+               return sumValue;
+       }
+
+       /**
+        * Computes the sum of all the elements in the given short array.
+        * 
+        * @param array
+        *        An array of shorts.
+        * @return
+        *        The sum of all elements in the array.
+        */
+       public static long sum(short[] array) {
+               long sumValue = 0;
+               for (int i = 0; i < array.length; i++) {
+                       sumValue += array[i];
+               }
+               return sumValue;
+       }
+
+       /**
+        * Computes the sum of all the elements in the given int array.
+        * 
+        * @param array
+        *        An array of ints.
+        * @return
+        *        The sum of all elements in the array.
+        */
+       public static long sum(int[] array) {
+               long sumValue = 0;
+               for (int i = 0; i < array.length; i++) {
+                       sumValue += array[i];
+               }
+               return sumValue;
+       }
+
+       /**
+        * Computes the sum of all the elements in the given long array.
+        * 
+        * @param array
+        *        An array of longs.
+        * @return
+        *        The sum of all elements in the array.
+        */
+       public static long sum(long[] array) {
+               long sumValue = 0;
+               for (int i = 0; i < array.length; i++) {
+                       sumValue += array[i];
+               }
+               return sumValue;
+       }
+
+       /**
+        * Computes the sum of all the elements in the given float array.
+        * 
+        * @param array
+        *        An array of floats.
+        * @return
+        *        The sum of all elements in the array.
+        */
+       public static double sum(float[] array) {
+               double sumValue = 0;
+               for (int i = 0; i < array.length; i++) {
+                       sumValue += array[i];
+               }
+               return sumValue;
+       }
+
+       /**
+        * Computes the sum of all the elements in the given double array.
+        * 
+        * @param array
+        *        An array of doubles.
+        * @return
+        *        The sum of all elements in the array.
+        */
+       public static double sum(double[] array) {
+               double sumValue = 0;
+               for (int i = 0; i < array.length; i++) {
+                       sumValue += array[i];
+               }
+               return sumValue;
+       }
+       
+       /**
+        * Finds the minimum number in the given array.
+        * 
+        * The passed array must be one of the following types: 
+        * <ul>
+        *   <li><code>byte[]</code></li>
+        *   <li><code>short[]</code></li>
+        *   <li><code>int[]</code></li>
+        *   <li><code>long[]</code></li>
+        *   <li><code>float[]</code></li>
+        *   <li><code>double[]</code></li>
+        * </ul>
+        * 
+        * @param array
+        *        An array.
+        * @return The smallest number, or <code>null</code> if the length of the
+        *        array is zero.
+        * @throws UnsupportedOperationException
+        *        If the passed array is not one of the supported types.
+        */
+       public static Number min(Object array) 
+               throws UnsupportedOperationException 
+       {       
+               if (array instanceof byte[]) {
+                       return min((byte[]) array);
+               } else if (array instanceof short[]) {
+                       return min((short[]) array);
+               } else if (array instanceof int[]) {
+                       return min((int[]) array);
+               } else if (array instanceof long[]) {
+                       return min((long[]) array);
+               } else if (array instanceof float[]) {
+                       return min((float[]) array);
+               } else if (array instanceof double[]) {
+                       return min((double[]) array);
+               } else {
+                       throw new UnsupportedOperationException();
+               }
+       }
+       
+       /**
+        * Finds the maximum number in the given array.
+        * 
+        * The passed array must be one of the following types: 
+        * <ul>
+        *   <li><code>byte[]</code></li>
+        *   <li><code>short[]</code></li>
+        *   <li><code>int[]</code></li>
+        *   <li><code>long[]</code></li>
+        *   <li><code>float[]</code></li>
+        *   <li><code>double[]</code></li>
+        * </ul>
+        * 
+        * @param array
+        *        An array.
+        * @return The largest number, or <code>null</code> if the length of the
+        *        array is zero.
+        * @throws UnsupportedOperationException
+        *        If the passed array is not one of the supported types.
+        */
+       public static Number max(Object array) 
+               throws UnsupportedOperationException 
+       {       
+               if (array instanceof byte[]) {
+                       return max((byte[]) array);
+               } else if (array instanceof short[]) {
+                       return max((short[]) array);
+               } else if (array instanceof int[]) {
+                       return max((int[]) array);
+               } else if (array instanceof long[]) {
+                       return max((long[]) array);
+               } else if (array instanceof float[]) {
+                       return max((float[]) array);
+               } else if (array instanceof double[]) {
+                       return max((double[]) array);
+               } else {
+                       throw new UnsupportedOperationException();
+               }
+       }
+       
+       /**
+        * Returns the smallest element in the given byte array.
+        * 
+        * @param array
+        *        An array of bytes.
+        * @return The smallest element, or <code>null</code> if the length of the
+        *        array is zero.
+        */
+       public static Byte min(byte[] array) {
+               if (array.length > 0) {
+                       byte minimum = array[0];
+                       for (int i = 1; i < array.length; i++) {
+                               if (array[i] < minimum) {
+                                       minimum = array[i];
+                               }
+                       }
+                       return minimum;
+               }
+               return null;
+       }
+
+       /**
+        * Returns the largest element in the given byte array.
+        * 
+        * @param array
+        *        An array of bytes.
+        * @return The largest element, or <code>null</code> if the length of the
+        *        array is zero.
+        */
+       public static Byte max(byte[] array) {
+               if (array.length > 0) {
+                       byte maximum = array[0];
+                       for (int i = 1; i < array.length; i++) {
+                               if (array[i] > maximum) {
+                                       maximum = array[i];
+                               }
+                       }
+                       return maximum;
+               }
+               return null;
+       }
+
+       /**
+        * Returns the smallest element in the given short array.
+        * 
+        * @param array
+        *        An array of shorts.
+        * @return The smallest element, or <code>null</code> if the length of the
+        *        array is zero.
+        */
+       public static Short min(short[] array) {
+               if (array.length > 0) {
+                       short minimum = array[0];
+                       for (int i = 1; i < array.length; i++) {
+                               if (array[i] < minimum) {
+                                       minimum = array[i];
+                               }
+                       }
+                       return minimum;
+               }
+               return null;
+       }
+
+       /**
+        * Returns the largest element in the given short array.
+        * 
+        * @param array
+        *        An array of shorts.
+        * @return The largest element, or <code>null</code> if the length of the
+        *        array is zero.
+        */
+       public static Short max(short[] array) {
+               if (array.length > 0) {
+                       short maximum = array[0];
+                       for (int i = 1; i < array.length; i++) {
+                               if (array[i] > maximum) {
+                                       maximum = array[i];
+                               }
+                       }
+                       return maximum;
+               }
+               return null;
+       }
+
+       /**
+        * Returns the smallest element in the given int array.
+        * 
+        * @param array
+        *        An array of ints.
+        * @return The smallest element, or <code>null</code> if the length of the
+        *        array is zero.
+        */
+       public static Integer min(int[] array) {
+               if (array.length > 0) {
+                       int minimum = array[0];
+                       for (int i = 1; i < array.length; i++) {
+                               if (array[i] < minimum) {
+                                       minimum = array[i];
+                               }
+                       }
+                       return minimum;
+               }
+               return null;
+       }
+
+       /**
+        * Returns the largest element in the given int array.
+        * 
+        * @param array
+        *        An array of ints.
+        * @return The largest element, or <code>null</code> if the length of the
+        *        array is zero.
+        */
+       public static Integer max(int[] array) {
+               if (array.length > 0) {
+                       int maximum = array[0];
+                       for (int i = 1; i < array.length; i++) {
+                               if (array[i] > maximum) {
+                                       maximum = array[i];
+                               }
+                       }
+                       return maximum;
+               }
+               return null;
+       }
+
+       /**
+        * Returns the smallest element in the given long array.
+        * 
+        * @param array
+        *        An array of longs.
+        * @return The smallest element, or <code>null</code> if the length of the
+        *        array is zero.
+        */
+       public static Long min(long[] array) {
+               if (array.length > 0) {
+                       long minimum = array[0];
+                       for (int i = 1; i < array.length; i++) {
+                               if (array[i] < minimum) {
+                                       minimum = array[i];
+                               }
+                       }
+                       return minimum;
+               }
+               return null;
+       }
+
+       /**
+        * Returns the largest element in the given long array.
+        * 
+        * @param array
+        *        An array of longs.
+        * @return The largest element, or <code>null</code> if the length of the
+        *        array is zero.
+        */
+       public static Long max(long[] array) {
+               if (array.length > 0) {
+                       long maximum = array[0];
+                       for (int i = 1; i < array.length; i++) {
+                               if (array[i] > maximum) {
+                                       maximum = array[i];
+                               }
+                       }
+                       return maximum;
+               }
+               return null;
+       }
+
+       /**
+        * Returns the smallest element in the given float array.
+        * 
+        * @param array
+        *        An array of floats.
+        * @return The smallest element, or <code>null</code> if the length of the
+        *        array is zero.
+        */
+       public static Float min(float[] array) {
+               if (array.length > 0) {
+                       float minimum = array[0];
+                       for (int i = 1; i < array.length; i++) {
+                               if (array[i] < minimum) {
+                                       minimum = array[i];
+                               }
+                       }
+                       return minimum;
+               }
+               return null;
+       }
+
+       /**
+        * Returns the largest element in the given float array.
+        * 
+        * @param array
+        *        An array of floats.
+        * @return The largest element, or <code>null</code> if the length of the
+        *        array is zero.
+        */
+       public static Float max(float[] array) {
+               if (array.length > 0) {
+                       float maximum = array[0];
+                       for (int i = 1; i < array.length; i++) {
+                               if (array[i] > maximum) {
+                                       maximum = array[i];
+                               }
+                       }
+                       return maximum;
+               }
+               return null;
+       }
+
+       /**
+        * Returns the smallest element in the given double array.
+        * 
+        * @param array
+        *        An array of doubles.
+        * @return The smallest element, or <code>null</code> if the length of the
+        *        array is zero.
+        */
+       public static Double min(double[] array) {
+               if (array.length > 0) {
+                       double minimum = array[0];
+                       for (int i = 1; i < array.length; i++) {
+                               if (array[i] < minimum) {
+                                       minimum = array[i];
+                               }
+                       }
+                       return minimum;
+               }
+               return null;
+       }
+
+       /**
+        * Returns the largest element in the given double array.
+        * 
+        * @param array
+        *        An array of doubles.
+        * @return The largest element, or <code>null</code> if the length of the
+        *        array is zero.
+        */
+       public static Double max(double[] array) {
+               if (array.length > 0) {
+                       double maximum = array[0];
+                       for (int i = 1; i < array.length; i++) {
+                               if (array[i] > maximum) {
+                                       maximum = array[i];
+                               }
+                       }
+                       return maximum;
+               }
+               return null;
+       }
+       
+       /**
+        * Copies an array from the specified source array, beginning at the
+     * specified position, to the specified position of the destination array.
+     * 
+     * This method uses {@link System#arraycopy(Object, int, Object, int, int)}
+     * if the source and destination array are of the same type, otherwise
+     * it sees if there is a compatible static copy method in this class
+     * that can perform the conversion copy. If one cannot be found, an
+     * {@link ArrayStoreException} is thrown.
+        *
+        * If the positions or lengths specified are out of range then an 
+        * {@link IndexOutOfBoundsException} is thrown and the destination is not
+        * modified.
+        *
+        * @param src
+        *        the source array.
+        * @param dst
+        *        the destination array.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws ArrayStoreException  
+        *        if an element in the source array could not be stored into the
+        *        destination array because of a type mismatch, and there is no
+        *        primitive copy conversion routine to handle the conversion.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(Object src, Object dst) {
+               copy(src, 0, dst, 0, Array.getLength(dst));
+       }
+       
+       /**
+        * Copies an array from the specified source array, beginning at the
+     * specified position, to the specified position of the destination array.
+     * 
+     * @see #copy(Object, int, Object, int, int)
+     * 
+        * @param src
+        *        the source array.
+        * @param srcPos
+        *        starting position in the source array.
+        * @param dst
+        *        the destination array.
+        * @param dstPos
+        *        starting position in the destination data.
+        * @param length   
+        *        the number of array elements to be copied.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws ArrayStoreException  
+        *        if an element in the source array could not be stored into the
+        *        destination array because of a type mismatch, and there is no
+        *        primitive copy conversion routine to handle the conversion.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(Object src, int srcPos, 
+                       Object dst, int dstPos, int length) 
+       {
+               if (dst.getClass().equals(src.getClass())) {
+
+                       // Use the fast system copy
+                       System.arraycopy(src, srcPos, dst, dstPos, length);
+
+               } else {
+                       // Try for arrays of different primitive types
+                       
+                       if (src instanceof byte[] && dst instanceof short[]) {
+
+                               // Copy from an array of bytes to array of shorts
+                               copy((byte[]) src, srcPos, (short[]) dst, dstPos, length);
+
+                       } else if (src instanceof byte[] && dst instanceof int[]) {
+
+                               // Copy from an array of bytes to array of ints
+                               copy((byte[]) src, srcPos, (int[]) dst, dstPos, length);
+
+                       } else if (src instanceof byte[] && dst instanceof long[]) {
+
+                               // Copy from an array of bytes to array of longs
+                               copy((byte[]) src, srcPos, (long[]) dst, dstPos, length);
+
+                       } else if (src instanceof byte[] && dst instanceof float[]) {
+
+                               // Copy from an array of bytes to array of floats
+                               copy((byte[]) src, srcPos, (float[]) dst, dstPos, length);
+
+                       } else if (src instanceof byte[] && dst instanceof double[]) {
+
+                               // Copy from an array of bytes to array of doubles
+                               copy((byte[]) src, srcPos, (double[]) dst, dstPos, length);
+
+                       } else if (src instanceof short[] && dst instanceof byte[]) {
+
+                               // Copy from an array of shorts to array of bytes
+                               copy((short[]) src, srcPos, (byte[]) dst, dstPos, length);
+
+                       } else if (src instanceof short[] && dst instanceof int[]) {
+
+                               // Copy from an array of shorts to array of ints
+                               copy((short[]) src, srcPos, (int[]) dst, dstPos, length);
+
+                       } else if (src instanceof short[] && dst instanceof long[]) {
+
+                               // Copy from an array of shorts to array of longs
+                               copy((short[]) src, srcPos, (long[]) dst, dstPos, length);
+
+                       } else if (src instanceof short[] && dst instanceof float[]) {
+
+                               // Copy from an array of shorts to array of floats
+                               copy((short[]) src, srcPos, (float[]) dst, dstPos, length);
+
+                       } else if (src instanceof short[] && dst instanceof double[]) {
+
+                               // Copy from an array of shorts to array of doubles
+                               copy((short[]) src, srcPos, (double[]) dst, dstPos, length);
+
+                       } else if (src instanceof int[] && dst instanceof byte[]) {
+
+                               // Copy from an array of ints to array of bytes
+                               copy((int[]) src, srcPos, (byte[]) dst, dstPos, length);
+
+                       } else if (src instanceof int[] && dst instanceof short[]) {
+
+                               // Copy from an array of ints to array of shorts
+                               copy((int[]) src, srcPos, (short[]) dst, dstPos, length);
+
+                       } else if (src instanceof int[] && dst instanceof long[]) {
+
+                               // Copy from an array of ints to array of longs
+                               copy((int[]) src, srcPos, (long[]) dst, dstPos, length);
+
+                       } else if (src instanceof int[] && dst instanceof float[]) {
+
+                               // Copy from an array of ints to array of floats
+                               copy((int[]) src, srcPos, (float[]) dst, dstPos, length);
+
+                       } else if (src instanceof int[] && dst instanceof double[]) {
+
+                               // Copy from an array of ints to array of doubles
+                               copy((int[]) src, srcPos, (double[]) dst, dstPos, length);
+
+                       } else if (src instanceof long[] && dst instanceof byte[]) {
+
+                               // Copy from an array of longs to array of bytes
+                               copy((long[]) src, srcPos, (byte[]) dst, dstPos, length);
+
+                       } else if (src instanceof long[] && dst instanceof short[]) {
+
+                               // Copy from an array of longs to array of shorts
+                               copy((long[]) src, srcPos, (short[]) dst, dstPos, length);
+
+                       } else if (src instanceof long[] && dst instanceof int[]) {
+
+                               // Copy from an array of longs to array of ints
+                               copy((long[]) src, srcPos, (int[]) dst, dstPos, length);
+
+                       } else if (src instanceof long[] && dst instanceof float[]) {
+
+                               // Copy from an array of longs to array of floats
+                               copy((long[]) src, srcPos, (float[]) dst, dstPos, length);
+
+                       } else if (src instanceof long[] && dst instanceof double[]) {
+
+                               // Copy from an array of longs to array of doubles
+                               copy((long[]) src, srcPos, (double[]) dst, dstPos, length);
+
+                       } else if (src instanceof float[] && dst instanceof byte[]) {
+
+                               // Copy from an array of floats to array of bytes
+                               copy((float[]) src, srcPos, (byte[]) dst, dstPos, length);
+
+                       } else if (src instanceof float[] && dst instanceof short[]) {
+
+                               // Copy from an array of floats to array of shorts
+                               copy((float[]) src, srcPos, (short[]) dst, dstPos, length);
+
+                       } else if (src instanceof float[] && dst instanceof int[]) {
+
+                               // Copy from an array of floats to array of ints
+                               copy((float[]) src, srcPos, (int[]) dst, dstPos, length);
+
+                       } else if (src instanceof float[] && dst instanceof long[]) {
+
+                               // Copy from an array of floats to array of longs
+                               copy((float[]) src, srcPos, (long[]) dst, dstPos, length);
+
+                       } else if (src instanceof float[] && dst instanceof double[]) {
+
+                               // Copy from an array of floats to array of doubles
+                               copy((float[]) src, srcPos, (double[]) dst, dstPos, length);
+
+                       } else if (src instanceof double[] && dst instanceof byte[]) {
+
+                               // Copy from an array of doubles to array of bytes
+                               copy((double[]) src, srcPos, (byte[]) dst, dstPos, length);
+
+                       } else if (src instanceof double[] && dst instanceof short[]) {
+
+                               // Copy from an array of doubles to array of shorts
+                               copy((double[]) src, srcPos, (short[]) dst, dstPos, length);
+
+                       } else if (src instanceof double[] && dst instanceof int[]) {
+
+                               // Copy from an array of doubles to array of ints
+                               copy((double[]) src, srcPos, (int[]) dst, dstPos, length);
+
+                       } else if (src instanceof double[] && dst instanceof long[]) {
+
+                               // Copy from an array of doubles to array of longs
+                               copy((double[]) src, srcPos, (long[]) dst, dstPos, length);
+
+                       } else if (src instanceof double[] && dst instanceof float[]) {
+
+                               // Copy from an array of doubles to array of floats
+                               copy((double[]) src, srcPos, (float[]) dst, dstPos, length);
+
+                       } else {
+
+                               throw new ArrayStoreException();
+                       }
+               }
+       }
+
+       /**
+        * Copy from an array of bytes to array of shorts. 
+        *
+        * The values will be cast to short. 
+        *
+        * If the positions or lengths specified are out of range then an 
+        * IndexOutOfBoundsException is thrown and the destination is not
+        * modified.
+        *
+        * @param src
+        *        the source array.
+        * @param srcPos
+        *        starting position in the source array.
+        * @param dst
+        *        the destination array.
+        * @param dstPos
+        *        starting position in the destination data.
+        * @param length   
+        *        the number of array elements to be copied.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(byte[] src, int srcPos, 
+                       short[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (short) src[srcPos++];
+               }
+       }
+
+       /**
+        * Copy from an array of bytes to array of shorts. 
+        *
+        * The values will be cast to short.
+        *
+        * @param src
+        *        the source array.
+        * @param dst
+        *        the destination array.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(byte[] src, short[] dst) {
+         copy(src, 0, dst, 0, dst.length);
+       }
+
+       /**
+        * Copy from an array of bytes to array of ints. 
+        *
+        * The values will be cast to int. 
+        *
+        * If the positions or lengths specified are out of range then an 
+        * IndexOutOfBoundsException is thrown and the destination is not
+        * modified.
+        *
+        * @param src
+        *        the source array.
+        * @param srcPos
+        *        starting position in the source array.
+        * @param dst
+        *        the destination array.
+        * @param dstPos
+        *        starting position in the destination data.
+        * @param length   
+        *        the number of array elements to be copied.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(byte[] src, int srcPos, 
+                       int[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (int) src[srcPos++];
+               }
+       }
+
+       /**
+        * Copy from an array of bytes to array of ints. 
+        *
+        * The values will be cast to int.
+        *
+        * @param src
+        *        the source array.
+        * @param dst
+        *        the destination array.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(byte[] src, int[] dst) {
+         copy(src, 0, dst, 0, dst.length);
+       }
+
+       /**
+        * Copy from an array of bytes to array of longs. 
+        *
+        * The values will be cast to long. 
+        *
+        * If the positions or lengths specified are out of range then an 
+        * IndexOutOfBoundsException is thrown and the destination is not
+        * modified.
+        *
+        * @param src
+        *        the source array.
+        * @param srcPos
+        *        starting position in the source array.
+        * @param dst
+        *        the destination array.
+        * @param dstPos
+        *        starting position in the destination data.
+        * @param length   
+        *        the number of array elements to be copied.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(byte[] src, int srcPos, 
+                       long[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (long) src[srcPos++];
+               }
+       }
+
+       /**
+        * Copy from an array of bytes to array of longs. 
+        *
+        * The values will be cast to long.
+        *
+        * @param src
+        *        the source array.
+        * @param dst
+        *        the destination array.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(byte[] src, long[] dst) {
+         copy(src, 0, dst, 0, dst.length);
+       }
+
+       /**
+        * Copy from an array of bytes to array of floats. 
+        *
+        * The values will be cast to float. 
+        *
+        * If the positions or lengths specified are out of range then an 
+        * IndexOutOfBoundsException is thrown and the destination is not
+        * modified.
+        *
+        * @param src
+        *        the source array.
+        * @param srcPos
+        *        starting position in the source array.
+        * @param dst
+        *        the destination array.
+        * @param dstPos
+        *        starting position in the destination data.
+        * @param length   
+        *        the number of array elements to be copied.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(byte[] src, int srcPos, 
+                       float[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (float) src[srcPos++];
+               }
+       }
+
+       /**
+        * Copy from an array of bytes to array of floats. 
+        *
+        * The values will be cast to float.
+        *
+        * @param src
+        *        the source array.
+        * @param dst
+        *        the destination array.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(byte[] src, float[] dst) {
+         copy(src, 0, dst, 0, dst.length);
+       }
+
+       /**
+        * Copy from an array of bytes to array of doubles. 
+        *
+        * The values will be cast to double. 
+        *
+        * If the positions or lengths specified are out of range then an 
+        * IndexOutOfBoundsException is thrown and the destination is not
+        * modified.
+        *
+        * @param src
+        *        the source array.
+        * @param srcPos
+        *        starting position in the source array.
+        * @param dst
+        *        the destination array.
+        * @param dstPos
+        *        starting position in the destination data.
+        * @param length   
+        *        the number of array elements to be copied.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(byte[] src, int srcPos, 
+                       double[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (double) src[srcPos++];
+               }
+       }
+
+       /**
+        * Copy from an array of bytes to array of doubles. 
+        *
+        * The values will be cast to double.
+        *
+        * @param src
+        *        the source array.
+        * @param dst
+        *        the destination array.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(byte[] src, double[] dst) {
+         copy(src, 0, dst, 0, dst.length);
+       }
+
+       /**
+        * Copy from an array of shorts to array of bytes. 
+        *
+        * The values will be cast to byte. 
+        *
+        * If the positions or lengths specified are out of range then an 
+        * IndexOutOfBoundsException is thrown and the destination is not
+        * modified.
+        *
+        * @param src
+        *        the source array.
+        * @param srcPos
+        *        starting position in the source array.
+        * @param dst
+        *        the destination array.
+        * @param dstPos
+        *        starting position in the destination data.
+        * @param length   
+        *        the number of array elements to be copied.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(short[] src, int srcPos, 
+                       byte[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (byte) src[srcPos++];
+               }
+       }
+
+       /**
+        * Copy from an array of shorts to array of bytes. 
+        *
+        * The values will be cast to byte.
+        *
+        * @param src
+        *        the source array.
+        * @param dst
+        *        the destination array.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(short[] src, byte[] dst) {
+         copy(src, 0, dst, 0, dst.length);
+       }
+
+       /**
+        * Copy from an array of shorts to array of ints. 
+        *
+        * The values will be cast to int. 
+        *
+        * If the positions or lengths specified are out of range then an 
+        * IndexOutOfBoundsException is thrown and the destination is not
+        * modified.
+        *
+        * @param src
+        *        the source array.
+        * @param srcPos
+        *        starting position in the source array.
+        * @param dst
+        *        the destination array.
+        * @param dstPos
+        *        starting position in the destination data.
+        * @param length   
+        *        the number of array elements to be copied.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(short[] src, int srcPos, 
+                       int[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (int) src[srcPos++];
+               }
+       }
+
+       /**
+        * Copy from an array of shorts to array of ints. 
+        *
+        * The values will be cast to int.
+        *
+        * @param src
+        *        the source array.
+        * @param dst
+        *        the destination array.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(short[] src, int[] dst) {
+         copy(src, 0, dst, 0, dst.length);
+       }
+
+       /**
+        * Copy from an array of shorts to array of longs. 
+        *
+        * The values will be cast to long. 
+        *
+        * If the positions or lengths specified are out of range then an 
+        * IndexOutOfBoundsException is thrown and the destination is not
+        * modified.
+        *
+        * @param src
+        *        the source array.
+        * @param srcPos
+        *        starting position in the source array.
+        * @param dst
+        *        the destination array.
+        * @param dstPos
+        *        starting position in the destination data.
+        * @param length   
+        *        the number of array elements to be copied.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(short[] src, int srcPos, 
+                       long[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (long) src[srcPos++];
+               }
+       }
+
+       /**
+        * Copy from an array of shorts to array of longs. 
+        *
+        * The values will be cast to long.
+        *
+        * @param src
+        *        the source array.
+        * @param dst
+        *        the destination array.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(short[] src, long[] dst) {
+         copy(src, 0, dst, 0, dst.length);
+       }
+
+       /**
+        * Copy from an array of shorts to array of floats. 
+        *
+        * The values will be cast to float. 
+        *
+        * If the positions or lengths specified are out of range then an 
+        * IndexOutOfBoundsException is thrown and the destination is not
+        * modified.
+        *
+        * @param src
+        *        the source array.
+        * @param srcPos
+        *        starting position in the source array.
+        * @param dst
+        *        the destination array.
+        * @param dstPos
+        *        starting position in the destination data.
+        * @param length   
+        *        the number of array elements to be copied.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(short[] src, int srcPos, 
+                       float[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (float) src[srcPos++];
+               }
+       }
+
+       /**
+        * Copy from an array of shorts to array of floats. 
+        *
+        * The values will be cast to float.
+        *
+        * @param src
+        *        the source array.
+        * @param dst
+        *        the destination array.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(short[] src, float[] dst) {
+         copy(src, 0, dst, 0, dst.length);
+       }
+
+       /**
+        * Copy from an array of shorts to array of doubles. 
+        *
+        * The values will be cast to double. 
+        *
+        * If the positions or lengths specified are out of range then an 
+        * IndexOutOfBoundsException is thrown and the destination is not
+        * modified.
+        *
+        * @param src
+        *        the source array.
+        * @param srcPos
+        *        starting position in the source array.
+        * @param dst
+        *        the destination array.
+        * @param dstPos
+        *        starting position in the destination data.
+        * @param length   
+        *        the number of array elements to be copied.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(short[] src, int srcPos, 
+                       double[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (double) src[srcPos++];
+               }
+       }
+
+       /**
+        * Copy from an array of shorts to array of doubles. 
+        *
+        * The values will be cast to double.
+        *
+        * @param src
+        *        the source array.
+        * @param dst
+        *        the destination array.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(short[] src, double[] dst) {
+         copy(src, 0, dst, 0, dst.length);
+       }
+
+       /**
+        * Copy from an array of ints to array of bytes. 
+        *
+        * The values will be cast to byte. 
+        *
+        * If the positions or lengths specified are out of range then an 
+        * IndexOutOfBoundsException is thrown and the destination is not
+        * modified.
+        *
+        * @param src
+        *        the source array.
+        * @param srcPos
+        *        starting position in the source array.
+        * @param dst
+        *        the destination array.
+        * @param dstPos
+        *        starting position in the destination data.
+        * @param length   
+        *        the number of array elements to be copied.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(int[] src, int srcPos, 
+                       byte[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (byte) src[srcPos++];
+               }
+       }
+
+       /**
+        * Copy from an array of ints to array of bytes. 
+        *
+        * The values will be cast to byte.
+        *
+        * @param src
+        *        the source array.
+        * @param dst
+        *        the destination array.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(int[] src, byte[] dst) {
+         copy(src, 0, dst, 0, dst.length);
+       }
+
+       /**
+        * Copy from an array of ints to array of shorts. 
+        *
+        * The values will be cast to short. 
+        *
+        * If the positions or lengths specified are out of range then an 
+        * IndexOutOfBoundsException is thrown and the destination is not
+        * modified.
+        *
+        * @param src
+        *        the source array.
+        * @param srcPos
+        *        starting position in the source array.
+        * @param dst
+        *        the destination array.
+        * @param dstPos
+        *        starting position in the destination data.
+        * @param length   
+        *        the number of array elements to be copied.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(int[] src, int srcPos, 
+                       short[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (short) src[srcPos++];
+               }
+       }
+
+       /**
+        * Copy from an array of ints to array of shorts. 
+        *
+        * The values will be cast to short.
+        *
+        * @param src
+        *        the source array.
+        * @param dst
+        *        the destination array.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(int[] src, short[] dst) {
+         copy(src, 0, dst, 0, dst.length);
+       }
+
+       /**
+        * Copy from an array of ints to array of longs. 
+        *
+        * The values will be cast to long. 
+        *
+        * If the positions or lengths specified are out of range then an 
+        * IndexOutOfBoundsException is thrown and the destination is not
+        * modified.
+        *
+        * @param src
+        *        the source array.
+        * @param srcPos
+        *        starting position in the source array.
+        * @param dst
+        *        the destination array.
+        * @param dstPos
+        *        starting position in the destination data.
+        * @param length   
+        *        the number of array elements to be copied.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(int[] src, int srcPos, 
+                       long[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (long) src[srcPos++];
+               }
+       }
+
+       /**
+        * Copy from an array of ints to array of longs. 
+        *
+        * The values will be cast to long.
+        *
+        * @param src
+        *        the source array.
+        * @param dst
+        *        the destination array.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(int[] src, long[] dst) {
+         copy(src, 0, dst, 0, dst.length);
+       }
+
+       /**
+        * Copy from an array of ints to array of floats. 
+        *
+        * The values will be cast to float. 
+        *
+        * If the positions or lengths specified are out of range then an 
+        * IndexOutOfBoundsException is thrown and the destination is not
+        * modified.
+        *
+        * @param src
+        *        the source array.
+        * @param srcPos
+        *        starting position in the source array.
+        * @param dst
+        *        the destination array.
+        * @param dstPos
+        *        starting position in the destination data.
+        * @param length   
+        *        the number of array elements to be copied.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(int[] src, int srcPos, 
+                       float[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (float) src[srcPos++];
+               }
+       }
+
+       /**
+        * Copy from an array of ints to array of floats. 
+        *
+        * The values will be cast to float.
+        *
+        * @param src
+        *        the source array.
+        * @param dst
+        *        the destination array.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(int[] src, float[] dst) {
+         copy(src, 0, dst, 0, dst.length);
+       }
+
+       /**
+        * Copy from an array of ints to array of doubles. 
+        *
+        * The values will be cast to double. 
+        *
+        * If the positions or lengths specified are out of range then an 
+        * IndexOutOfBoundsException is thrown and the destination is not
+        * modified.
+        *
+        * @param src
+        *        the source array.
+        * @param srcPos
+        *        starting position in the source array.
+        * @param dst
+        *        the destination array.
+        * @param dstPos
+        *        starting position in the destination data.
+        * @param length   
+        *        the number of array elements to be copied.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(int[] src, int srcPos, 
+                       double[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (double) src[srcPos++];
+               }
+       }
+
+       /**
+        * Copy from an array of ints to array of doubles. 
+        *
+        * The values will be cast to double.
+        *
+        * @param src
+        *        the source array.
+        * @param dst
+        *        the destination array.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(int[] src, double[] dst) {
+         copy(src, 0, dst, 0, dst.length);
+       }
+
+       /**
+        * Copy from an array of longs to array of bytes. 
+        *
+        * The values will be cast to byte. 
+        *
+        * If the positions or lengths specified are out of range then an 
+        * IndexOutOfBoundsException is thrown and the destination is not
+        * modified.
+        *
+        * @param src
+        *        the source array.
+        * @param srcPos
+        *        starting position in the source array.
+        * @param dst
+        *        the destination array.
+        * @param dstPos
+        *        starting position in the destination data.
+        * @param length   
+        *        the number of array elements to be copied.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(long[] src, int srcPos, 
+                       byte[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (byte) src[srcPos++];
+               }
+       }
+
+       /**
+        * Copy from an array of longs to array of bytes. 
+        *
+        * The values will be cast to byte.
+        *
+        * @param src
+        *        the source array.
+        * @param dst
+        *        the destination array.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(long[] src, byte[] dst) {
+         copy(src, 0, dst, 0, dst.length);
+       }
+
+       /**
+        * Copy from an array of longs to array of shorts. 
+        *
+        * The values will be cast to short. 
+        *
+        * If the positions or lengths specified are out of range then an 
+        * IndexOutOfBoundsException is thrown and the destination is not
+        * modified.
+        *
+        * @param src
+        *        the source array.
+        * @param srcPos
+        *        starting position in the source array.
+        * @param dst
+        *        the destination array.
+        * @param dstPos
+        *        starting position in the destination data.
+        * @param length   
+        *        the number of array elements to be copied.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(long[] src, int srcPos, 
+                       short[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (short) src[srcPos++];
+               }
+       }
+
+       /**
+        * Copy from an array of longs to array of shorts. 
+        *
+        * The values will be cast to short.
+        *
+        * @param src
+        *        the source array.
+        * @param dst
+        *        the destination array.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(long[] src, short[] dst) {
+         copy(src, 0, dst, 0, dst.length);
+       }
+
+       /**
+        * Copy from an array of longs to array of ints. 
+        *
+        * The values will be cast to int. 
+        *
+        * If the positions or lengths specified are out of range then an 
+        * IndexOutOfBoundsException is thrown and the destination is not
+        * modified.
+        *
+        * @param src
+        *        the source array.
+        * @param srcPos
+        *        starting position in the source array.
+        * @param dst
+        *        the destination array.
+        * @param dstPos
+        *        starting position in the destination data.
+        * @param length   
+        *        the number of array elements to be copied.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(long[] src, int srcPos, 
+                       int[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (int) src[srcPos++];
+               }
+       }
+
+       /**
+        * Copy from an array of longs to array of ints. 
+        *
+        * The values will be cast to int.
+        *
+        * @param src
+        *        the source array.
+        * @param dst
+        *        the destination array.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(long[] src, int[] dst) {
+         copy(src, 0, dst, 0, dst.length);
+       }
+
+       /**
+        * Copy from an array of longs to array of floats. 
+        *
+        * The values will be cast to float. 
+        *
+        * If the positions or lengths specified are out of range then an 
+        * IndexOutOfBoundsException is thrown and the destination is not
+        * modified.
+        *
+        * @param src
+        *        the source array.
+        * @param srcPos
+        *        starting position in the source array.
+        * @param dst
+        *        the destination array.
+        * @param dstPos
+        *        starting position in the destination data.
+        * @param length   
+        *        the number of array elements to be copied.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(long[] src, int srcPos, 
+                       float[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (float) src[srcPos++];
+               }
+       }
+
+       /**
+        * Copy from an array of longs to array of floats. 
+        *
+        * The values will be cast to float.
+        *
+        * @param src
+        *        the source array.
+        * @param dst
+        *        the destination array.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(long[] src, float[] dst) {
+         copy(src, 0, dst, 0, dst.length);
+       }
+
+       /**
+        * Copy from an array of longs to array of doubles. 
+        *
+        * The values will be cast to double. 
+        *
+        * If the positions or lengths specified are out of range then an 
+        * IndexOutOfBoundsException is thrown and the destination is not
+        * modified.
+        *
+        * @param src
+        *        the source array.
+        * @param srcPos
+        *        starting position in the source array.
+        * @param dst
+        *        the destination array.
+        * @param dstPos
+        *        starting position in the destination data.
+        * @param length   
+        *        the number of array elements to be copied.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(long[] src, int srcPos, 
+                       double[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (double) src[srcPos++];
+               }
+       }
+
+       /**
+        * Copy from an array of longs to array of doubles. 
+        *
+        * The values will be cast to double.
+        *
+        * @param src
+        *        the source array.
+        * @param dst
+        *        the destination array.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(long[] src, double[] dst) {
+         copy(src, 0, dst, 0, dst.length);
+       }
+
+       /**
+        * Copy from an array of floats to array of bytes. 
+        *
+        * The values will be cast to byte. 
+        *
+        * If the positions or lengths specified are out of range then an 
+        * IndexOutOfBoundsException is thrown and the destination is not
+        * modified.
+        *
+        * @param src
+        *        the source array.
+        * @param srcPos
+        *        starting position in the source array.
+        * @param dst
+        *        the destination array.
+        * @param dstPos
+        *        starting position in the destination data.
+        * @param length   
+        *        the number of array elements to be copied.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(float[] src, int srcPos, 
+                       byte[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (byte) src[srcPos++];
+               }
+       }
+
+       /**
+        * Copy from an array of floats to array of bytes. 
+        *
+        * The values will be cast to byte.
+        *
+        * @param src
+        *        the source array.
+        * @param dst
+        *        the destination array.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(float[] src, byte[] dst) {
+         copy(src, 0, dst, 0, dst.length);
+       }
+
+       /**
+        * Copy from an array of floats to array of shorts. 
+        *
+        * The values will be cast to short. 
+        *
+        * If the positions or lengths specified are out of range then an 
+        * IndexOutOfBoundsException is thrown and the destination is not
+        * modified.
+        *
+        * @param src
+        *        the source array.
+        * @param srcPos
+        *        starting position in the source array.
+        * @param dst
+        *        the destination array.
+        * @param dstPos
+        *        starting position in the destination data.
+        * @param length   
+        *        the number of array elements to be copied.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(float[] src, int srcPos, 
+                       short[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (short) src[srcPos++];
+               }
+       }
+
+       /**
+        * Copy from an array of floats to array of shorts. 
+        *
+        * The values will be cast to short.
+        *
+        * @param src
+        *        the source array.
+        * @param dst
+        *        the destination array.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(float[] src, short[] dst) {
+         copy(src, 0, dst, 0, dst.length);
+       }
+
+       /**
+        * Copy from an array of floats to array of ints. 
+        *
+        * The values will be cast to int. 
+        *
+        * If the positions or lengths specified are out of range then an 
+        * IndexOutOfBoundsException is thrown and the destination is not
+        * modified.
+        *
+        * @param src
+        *        the source array.
+        * @param srcPos
+        *        starting position in the source array.
+        * @param dst
+        *        the destination array.
+        * @param dstPos
+        *        starting position in the destination data.
+        * @param length   
+        *        the number of array elements to be copied.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(float[] src, int srcPos, 
+                       int[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (int) src[srcPos++];
+               }
+       }
+
+       /**
+        * Copy from an array of floats to array of ints. 
+        *
+        * The values will be cast to int.
+        *
+        * @param src
+        *        the source array.
+        * @param dst
+        *        the destination array.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(float[] src, int[] dst) {
+         copy(src, 0, dst, 0, dst.length);
+       }
+
+       /**
+        * Copy from an array of floats to array of longs. 
+        *
+        * The values will be cast to long. 
+        *
+        * If the positions or lengths specified are out of range then an 
+        * IndexOutOfBoundsException is thrown and the destination is not
+        * modified.
+        *
+        * @param src
+        *        the source array.
+        * @param srcPos
+        *        starting position in the source array.
+        * @param dst
+        *        the destination array.
+        * @param dstPos
+        *        starting position in the destination data.
+        * @param length   
+        *        the number of array elements to be copied.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(float[] src, int srcPos, 
+                       long[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (long) src[srcPos++];
+               }
+       }
+
+       /**
+        * Copy from an array of floats to array of longs. 
+        *
+        * The values will be cast to long.
+        *
+        * @param src
+        *        the source array.
+        * @param dst
+        *        the destination array.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(float[] src, long[] dst) {
+         copy(src, 0, dst, 0, dst.length);
+       }
+
+       /**
+        * Copy from an array of floats to array of doubles. 
+        *
+        * The values will be cast to double. 
+        *
+        * If the positions or lengths specified are out of range then an 
+        * IndexOutOfBoundsException is thrown and the destination is not
+        * modified.
+        *
+        * @param src
+        *        the source array.
+        * @param srcPos
+        *        starting position in the source array.
+        * @param dst
+        *        the destination array.
+        * @param dstPos
+        *        starting position in the destination data.
+        * @param length   
+        *        the number of array elements to be copied.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(float[] src, int srcPos, 
+                       double[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (double) src[srcPos++];
+               }
+       }
+
+       /**
+        * Copy from an array of floats to array of doubles. 
+        *
+        * The values will be cast to double.
+        *
+        * @param src
+        *        the source array.
+        * @param dst
+        *        the destination array.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(float[] src, double[] dst) {
+         copy(src, 0, dst, 0, dst.length);
+       }
+
+       /**
+        * Copy from an array of doubles to array of bytes. 
+        *
+        * The values will be cast to byte. 
+        *
+        * If the positions or lengths specified are out of range then an 
+        * IndexOutOfBoundsException is thrown and the destination is not
+        * modified.
+        *
+        * @param src
+        *        the source array.
+        * @param srcPos
+        *        starting position in the source array.
+        * @param dst
+        *        the destination array.
+        * @param dstPos
+        *        starting position in the destination data.
+        * @param length   
+        *        the number of array elements to be copied.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(double[] src, int srcPos, 
+                       byte[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (byte) src[srcPos++];
+               }
+       }
+
+       /**
+        * Copy from an array of doubles to array of bytes. 
+        *
+        * The values will be cast to byte.
+        *
+        * @param src
+        *        the source array.
+        * @param dst
+        *        the destination array.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(double[] src, byte[] dst) {
+         copy(src, 0, dst, 0, dst.length);
+       }
+
+       /**
+        * Copy from an array of doubles to array of shorts. 
+        *
+        * The values will be cast to short. 
+        *
+        * If the positions or lengths specified are out of range then an 
+        * IndexOutOfBoundsException is thrown and the destination is not
+        * modified.
+        *
+        * @param src
+        *        the source array.
+        * @param srcPos
+        *        starting position in the source array.
+        * @param dst
+        *        the destination array.
+        * @param dstPos
+        *        starting position in the destination data.
+        * @param length   
+        *        the number of array elements to be copied.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(double[] src, int srcPos, 
+                       short[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (short) src[srcPos++];
+               }
+       }
+
+       /**
+        * Copy from an array of doubles to array of shorts. 
+        *
+        * The values will be cast to short.
+        *
+        * @param src
+        *        the source array.
+        * @param dst
+        *        the destination array.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(double[] src, short[] dst) {
+         copy(src, 0, dst, 0, dst.length);
+       }
+
+       /**
+        * Copy from an array of doubles to array of ints. 
+        *
+        * The values will be cast to int. 
+        *
+        * If the positions or lengths specified are out of range then an 
+        * IndexOutOfBoundsException is thrown and the destination is not
+        * modified.
+        *
+        * @param src
+        *        the source array.
+        * @param srcPos
+        *        starting position in the source array.
+        * @param dst
+        *        the destination array.
+        * @param dstPos
+        *        starting position in the destination data.
+        * @param length   
+        *        the number of array elements to be copied.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(double[] src, int srcPos, 
+                       int[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (int) src[srcPos++];
+               }
+       }
+
+       /**
+        * Copy from an array of doubles to array of ints. 
+        *
+        * The values will be cast to int.
+        *
+        * @param src
+        *        the source array.
+        * @param dst
+        *        the destination array.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(double[] src, int[] dst) {
+         copy(src, 0, dst, 0, dst.length);
+       }
+
+       /**
+        * Copy from an array of doubles to array of longs. 
+        *
+        * The values will be cast to long. 
+        *
+        * If the positions or lengths specified are out of range then an 
+        * IndexOutOfBoundsException is thrown and the destination is not
+        * modified.
+        *
+        * @param src
+        *        the source array.
+        * @param srcPos
+        *        starting position in the source array.
+        * @param dst
+        *        the destination array.
+        * @param dstPos
+        *        starting position in the destination data.
+        * @param length   
+        *        the number of array elements to be copied.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(double[] src, int srcPos, 
+                       long[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (long) src[srcPos++];
+               }
+       }
+
+       /**
+        * Copy from an array of doubles to array of longs. 
+        *
+        * The values will be cast to long.
+        *
+        * @param src
+        *        the source array.
+        * @param dst
+        *        the destination array.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(double[] src, long[] dst) {
+         copy(src, 0, dst, 0, dst.length);
+       }
+
+       /**
+        * Copy from an array of doubles to array of floats. 
+        *
+        * The values will be cast to float. 
+        *
+        * If the positions or lengths specified are out of range then an 
+        * IndexOutOfBoundsException is thrown and the destination is not
+        * modified.
+        *
+        * @param src
+        *        the source array.
+        * @param srcPos
+        *        starting position in the source array.
+        * @param dst
+        *        the destination array.
+        * @param dstPos
+        *        starting position in the destination data.
+        * @param length   
+        *        the number of array elements to be copied.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(double[] src, int srcPos, 
+                       float[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (float) src[srcPos++];
+               }
+       }
+
+       /**
+        * Copy from an array of doubles to array of floats. 
+        *
+        * The values will be cast to float.
+        *
+        * @param src
+        *        the source array.
+        * @param dst
+        *        the destination array.
+        * @throws IndexOutOfBoundsException  
+        *        if copying would cause access of data outside array bounds.
+        * @throws NullPointerException 
+        *        if either <code>src</code> or <code>dest</code> is 
+        *        <code>null</code>.
+        */
+       public static void copy(double[] src, float[] dst) {
+         copy(src, 0, dst, 0, dst.length);
+       }
+
+       /**
+        * Throws an {@link IndexOutOfBoundsException} if the arguments
+        * would result in an array copy that would go out of bounds.
+        */
+       private static void checkCopy(int srcLen, int srcPos, 
+                       int dstLen, int dstPos, int length) 
+       {
+               if (srcPos < 0) {
+                       throw new IndexOutOfBoundsException("srcPos < 0");
+               }
+               
+               if (dstPos < 0) {
+                       throw new IndexOutOfBoundsException("dstPos < 0");
+               }
+               
+               if (length < 0) {
+                       throw new IndexOutOfBoundsException("length < 0");
+               }
+               
+               if (srcPos + length > srcLen) {
+                       throw new IndexOutOfBoundsException("srcPos + length > src.length");
+               }
+               
+               if (dstPos + length > dstLen) {
+                       throw new IndexOutOfBoundsException("dstPos + length > dst.length");
+               }
+       }
+}
diff --git a/Annotation/src/ie/dcu/array/Filter$Byte.class b/Annotation/src/ie/dcu/array/Filter$Byte.class
new file mode 100644 (file)
index 0000000..bdcc8ab
Binary files /dev/null and b/Annotation/src/ie/dcu/array/Filter$Byte.class differ
diff --git a/Annotation/src/ie/dcu/array/Filter$Double.class b/Annotation/src/ie/dcu/array/Filter$Double.class
new file mode 100644 (file)
index 0000000..d447605
Binary files /dev/null and b/Annotation/src/ie/dcu/array/Filter$Double.class differ
diff --git a/Annotation/src/ie/dcu/array/Filter$Float.class b/Annotation/src/ie/dcu/array/Filter$Float.class
new file mode 100644 (file)
index 0000000..27da8a0
Binary files /dev/null and b/Annotation/src/ie/dcu/array/Filter$Float.class differ
diff --git a/Annotation/src/ie/dcu/array/Filter$Integer.class b/Annotation/src/ie/dcu/array/Filter$Integer.class
new file mode 100644 (file)
index 0000000..d936b83
Binary files /dev/null and b/Annotation/src/ie/dcu/array/Filter$Integer.class differ
diff --git a/Annotation/src/ie/dcu/array/Filter$Long.class b/Annotation/src/ie/dcu/array/Filter$Long.class
new file mode 100644 (file)
index 0000000..17c390d
Binary files /dev/null and b/Annotation/src/ie/dcu/array/Filter$Long.class differ
diff --git a/Annotation/src/ie/dcu/array/Filter$Short.class b/Annotation/src/ie/dcu/array/Filter$Short.class
new file mode 100644 (file)
index 0000000..d0e77c5
Binary files /dev/null and b/Annotation/src/ie/dcu/array/Filter$Short.class differ
diff --git a/Annotation/src/ie/dcu/array/Filter.class b/Annotation/src/ie/dcu/array/Filter.class
new file mode 100644 (file)
index 0000000..0272591
Binary files /dev/null and b/Annotation/src/ie/dcu/array/Filter.class differ
diff --git a/Annotation/src/ie/dcu/array/Filter.java b/Annotation/src/ie/dcu/array/Filter.java
new file mode 100644 (file)
index 0000000..fad522b
--- /dev/null
@@ -0,0 +1,116 @@
+package ie.dcu.array;
+
+/**
+ * Interfaces for filters
+ * 
+ * @author Kevin McGuinness
+ */
+public interface Filter {
+       
+       /**
+        * Returns <code>true</code> if the given value should be retained.
+        * 
+     * @param object
+     *        An object.
+     * @return
+     *        <code>true</code> if the value should be retained.
+        */
+       public boolean retain(Object object);
+
+
+       /**
+        * An byte filter.
+        */
+       public interface Byte {
+               
+               /**
+                * Returns <code>true</code> if the given value should be retained.
+                * 
+                * @param value
+                *        An byte value.
+                * @return
+                *        <code>true</code> if the value should be retained.
+                */
+               public boolean retain(byte value);
+       }
+
+       /**
+        * An short filter.
+        */
+       public interface Short {
+               
+               /**
+                * Returns <code>true</code> if the given value should be retained.
+                * 
+                * @param value
+                *        An short value.
+                * @return
+                *        <code>true</code> if the value should be retained.
+                */
+               public boolean retain(short value);
+       }
+
+       /**
+        * An int filter.
+        */
+       public interface Integer {
+               
+               /**
+                * Returns <code>true</code> if the given value should be retained.
+                * 
+                * @param value
+                *        An int value.
+                * @return
+                *        <code>true</code> if the value should be retained.
+                */
+               public boolean retain(int value);
+       }
+
+       /**
+        * An long filter.
+        */
+       public interface Long {
+               
+               /**
+                * Returns <code>true</code> if the given value should be retained.
+                * 
+                * @param value
+                *        An long value.
+                * @return
+                *        <code>true</code> if the value should be retained.
+                */
+               public boolean retain(long value);
+       }
+
+       /**
+        * An float filter.
+        */
+       public interface Float {
+               
+               /**
+                * Returns <code>true</code> if the given value should be retained.
+                * 
+                * @param value
+                *        An float value.
+                * @return
+                *        <code>true</code> if the value should be retained.
+                */
+               public boolean retain(float value);
+       }
+
+       /**
+        * An double filter.
+        */
+       public interface Double {
+               
+               /**
+                * Returns <code>true</code> if the given value should be retained.
+                * 
+                * @param value
+                *        An double value.
+                * @return
+                *        <code>true</code> if the value should be retained.
+                */
+               public boolean retain(double value);
+       }
+}
diff --git a/Annotation/src/ie/dcu/array/Reduction$Double.class b/Annotation/src/ie/dcu/array/Reduction$Double.class
new file mode 100644 (file)
index 0000000..c9a4a09
Binary files /dev/null and b/Annotation/src/ie/dcu/array/Reduction$Double.class differ
diff --git a/Annotation/src/ie/dcu/array/Reduction$Long.class b/Annotation/src/ie/dcu/array/Reduction$Long.class
new file mode 100644 (file)
index 0000000..7c74f1f
Binary files /dev/null and b/Annotation/src/ie/dcu/array/Reduction$Long.class differ
diff --git a/Annotation/src/ie/dcu/array/Reduction.class b/Annotation/src/ie/dcu/array/Reduction.class
new file mode 100644 (file)
index 0000000..6c83c51
Binary files /dev/null and b/Annotation/src/ie/dcu/array/Reduction.class differ
diff --git a/Annotation/src/ie/dcu/array/Reduction.java b/Annotation/src/ie/dcu/array/Reduction.java
new file mode 100644 (file)
index 0000000..6e29fb4
--- /dev/null
@@ -0,0 +1,64 @@
+package ie.dcu.array;
+
+/**
+ * A reduce operation.
+ * 
+ * @author Kevin McGuinness
+ */
+public interface Reduction<T, U> {
+
+       /**
+        * Perform a reduction.
+        * 
+        * @param accumulator 
+        *        The accumulated value so far.
+        * @param value
+        *        The next value in the array.
+        * @param index
+        *        The index of the value in the array.
+        * @return
+        *        The result of the reduction.
+        */
+       public U reduce(U accumulator, T value, int index);
+       
+       
+       /**
+        * A long width reduction.
+        */
+       public interface Long {
+               
+               /**
+                * Perform a reduction.
+                * 
+                * @param accumulator 
+                *        The accumulated value so far.
+                * @param value
+                *        The next value in the array.
+                * @param index
+                *        The index of the value in the array.
+                * @return
+                *        The result of the reduction.
+                */
+               public long reduce(long accumulator, long value, int index);
+       }
+       
+       /**
+        * A double precision reduction.
+        */
+       public interface Double {
+               
+               /**
+                * Perform a reduction.
+                * 
+                * @param accumulator 
+                *        The accumulated value so far.
+                * @param value
+                *        The next value in the array.
+                * @param index
+                *        The index of the value in the array.
+                * @return
+                *        The result of the reduction.
+                */
+               public long reduce(double accumulator, double value, int index);
+       }
+}
diff --git a/Annotation/src/ie/dcu/auto/AutomationData$Listener.class b/Annotation/src/ie/dcu/auto/AutomationData$Listener.class
new file mode 100644 (file)
index 0000000..2efff2e
Binary files /dev/null and b/Annotation/src/ie/dcu/auto/AutomationData$Listener.class differ
diff --git a/Annotation/src/ie/dcu/auto/AutomationData.class b/Annotation/src/ie/dcu/auto/AutomationData.class
new file mode 100644 (file)
index 0000000..c0785af
Binary files /dev/null and b/Annotation/src/ie/dcu/auto/AutomationData.class differ
diff --git a/Annotation/src/ie/dcu/auto/AutomationData.java b/Annotation/src/ie/dcu/auto/AutomationData.java
new file mode 100644 (file)
index 0000000..0eb9b8c
--- /dev/null
@@ -0,0 +1,369 @@
+package ie.dcu.auto;
+
+import ie.dcu.auto.automator.*;
+import ie.dcu.eval.*;
+import ie.dcu.matrix.ByteMatrix;
+import ie.dcu.segment.*;
+
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * Container class for data needed for the automation.
+ * 
+ * @author Kevin McGuinness
+ */
+public class AutomationData {
+       
+       public static interface Listener {
+               public void segmentationContextChanged(AutomationData data);
+               public void segmentationContextUpdated(AutomationData automationData);
+               public void groundTruthMaskChanged(AutomationData data);
+               public void foregroundErrorChanged(AutomationData data);
+               public void backgroundErrorChanged(AutomationData data);
+               public void segmenterChanged(AutomationData data);
+               public void evaluationMeasuresChanged(AutomationData data);
+               public void evaluationResultsAdded(AutomationData data);
+               public void evaluationResultsCleared(AutomationData data);
+               public void automatorStateChanged(AutomationData data);
+               public void logUpdated(AutomationData data, String message);
+               
+       }
+       
+       private SegmentationContext segmentationContext;
+       private SegmentationMask groundTruthMask;
+       private ByteMatrix foregroundError;
+       private ByteMatrix backgroundError;
+       private EvaluationResults evaluationResults;
+       private List<Evaluator> evaluators;
+       private Segmenter segmenter;
+       private Automator automator;
+       private List<Listener> listeners;
+       
+       public AutomationData() {
+               evaluators = new LinkedList<Evaluator>();
+               listeners = new LinkedList<Listener>();
+               evaluationResults = new EvaluationResults();
+               automator = new DeterministicAutomator(this);
+       }
+       
+       public void setAutomator(Automator automator) {
+               if (automator == null) {
+                       throw new IllegalArgumentException();
+               }
+               
+               // Reset old automator
+               this.automator.reset();
+               
+               // Set new automator
+               this.automator = automator;
+               
+               // Reset new automator
+               this.automator.reset();
+       }
+       
+       public void dispose() {
+               listeners.clear();
+               evaluators.clear();
+               setSegmentationContext(null);
+       }
+       
+       public void addDefaultEvaluators() {
+               addEvaluator(new BestEvaluator());
+       }
+       
+       public void addEvaluator(Evaluator e) {
+               evaluators.add(e);
+               updateEvaluationMeasures();
+       }
+       
+       public void removeEvaluator(Evaluator e) {
+               evaluators.remove(e);
+               updateEvaluationMeasures();
+       }
+       
+       public List<Evaluator> getEvaluators() {
+               return Collections.unmodifiableList(evaluators);
+       }
+       
+       public SegmentationContext getSegmentationContext() {
+               return segmentationContext;
+       }
+       
+       public void setSegmentationContext(SegmentationContext context) {
+               if (segmentationContext != context) {
+                       
+                       // Tidy up
+                       if (segmentationContext != null) {
+                               
+                               if (segmenter != null) {
+                                       segmenter.finish(segmentationContext);
+                               }
+                               
+                               if (!segmentationContext.isDisposed()) {
+                                       segmentationContext.dispose();
+                               }
+                               
+                               segmentationContext = null;
+                       }
+                       
+                       // Set
+                       this.segmentationContext = context;
+                       fireSegmentationContextChanged();
+               }
+       }
+       
+       public void setSegmenter(Segmenter segmenter) {
+               if (this.segmenter != segmenter) {
+                       
+                       // Tidy up
+                       if (this.segmenter != null) {
+                               if (segmentationContext != null) {
+                                       this.segmenter.finish(segmentationContext);
+                               }
+                               this.segmenter = null;
+                       }
+                       
+                       this.segmenter = segmenter;
+                       this.automator.reset();
+                       fireSegmenterChanged();
+               }
+       }
+       
+       public Segmenter getSegmenter() {
+               return segmenter;
+       }
+
+       public SegmentationMask getGroundTruthMask() {
+               return groundTruthMask;
+       }
+       
+       public void setGroundTruthMask(SegmentationMask mask) {
+               if (this.groundTruthMask != mask) {
+                       this.groundTruthMask = mask;
+                       fireGroundTruthMaskChanged();
+               }
+       }
+       
+       public ByteMatrix getForegroundError() {
+               return foregroundError;
+       }
+
+       public void setForegroundError(ByteMatrix error) {
+               if (this.foregroundError != error) {
+                       this.foregroundError = error;
+                       fireForegroundErrorChanged();
+               }
+       }
+
+       public ByteMatrix getBackgroundError() {
+               return backgroundError;
+       }
+
+       public void setBackgroundError(ByteMatrix error) {
+               if (this.backgroundError != error) {
+                       this.backgroundError = error;
+                       fireBackgroundErrorChanged();
+               }
+       }
+       
+       public void clearEvaluationResults() {
+               if (evaluationResults.getResultCount() > 0) {
+                       evaluationResults.clearResults();
+                       fireEvaluationResultsCleared();
+               }
+       }
+       
+       private void updateEvaluationMeasures() {
+               List<String> headings = new ArrayList<String>();
+               for (Evaluator e : evaluators) {
+                       String[] measures = e.getMeasures();
+                       for (String m : measures) {
+                               headings.add(m);
+                       }
+               }
+               
+               String[] measures = headings.toArray(new String[headings.size()]);
+               setEvaluationMeasures(measures);
+       }
+       
+       public void evaluate() {
+               SegmentationMask mask = segmentationContext.getMask();
+               
+               double[] values = new double[evaluationResults.getMeasureCount()];
+               for (Evaluator e : evaluators) {
+                       e.run(mask, groundTruthMask);
+                       
+                       String[] measures = e.getMeasures();
+                       for (String m : measures) {
+                               int idx = evaluationResults.indexOfMeasure(m);
+                               values[idx] = e.getMeasure(m);
+                       }
+               }
+               
+               addEvaluationResult(values);
+       }
+
+       private void addEvaluationResult(double[] result) {
+               evaluationResults.addResults(result);
+               fireEvaluationResultAdded();
+       }
+       
+       private void setEvaluationMeasures(String[] measures) {
+               clearEvaluationResults();
+               evaluationResults.setMeasures(measures);
+               fireEvaluationMeasuresChanged();
+       }
+       
+       public EvaluationResults getEvaluationResults() {
+               return evaluationResults;
+       }
+       
+       public Automator getAutomator() {
+               return automator;
+       }
+
+       public void load(AutomationInput input) throws IOException {
+               SegmentationContext ctx = SegmentationContext.create(input.imageFile);
+               SegmentationMask mask = SegmentationMask.read(input.groundTruthFile);
+               
+               if (ctx.getBounds().equals(mask.getBounds())) {
+                       
+                       clearEvaluationResults();
+                       setSegmentationContext(ctx);
+                       setGroundTruthMask(mask);
+                       automator.reset();
+                       
+                       
+               } else {
+                       ctx.dispose();
+                       throw new IOException("Images are not the same size");
+               }
+       }
+       
+       public void updateSegmentationError() {
+               
+               SegmentationMask mask = segmentationContext.getMask();
+               
+               int rows = groundTruthMask.height;
+               int cols = groundTruthMask.width;
+               
+               if (foregroundError == null || 
+                       foregroundError.cols != cols || 
+                       foregroundError.rows != rows) 
+               {
+                       foregroundError = new ByteMatrix(rows, cols);
+               }
+               
+               if (backgroundError == null || 
+                       backgroundError.cols != cols || 
+                       backgroundError.rows != rows) 
+               {
+                       backgroundError = new ByteMatrix(rows, cols);
+               }
+               
+               foregroundError.fill(0);
+               backgroundError.fill(0);
+               
+               for (int i = 0; i < rows; i++) {
+                       int k = i * cols;
+
+                       for (int j = 0; j < cols; j++, k++) {
+                               int v = groundTruthMask.values[k];
+                               if (v != mask.values[k]) {
+                                       switch (v) {
+                                       case SegmentationMask.FOREGROUND:
+                                               foregroundError.values[k] = Constants.ERROR_VALUE;
+                                               break;
+                                       case SegmentationMask.BACKGROUND:
+                                               backgroundError.values[k] = Constants.ERROR_VALUE;
+                                               break;
+                                       }
+                                       
+                               } 
+                       }
+               }
+               
+               fireForegroundErrorChanged();
+               fireBackgroundErrorChanged();
+       }
+       
+       public void logActivity(String message, Object ... args) {
+               String log = String.format(message, args) + "\n";
+               fireLogUpdated(log);
+       }
+
+       private void fireLogUpdated(String message) {
+               for (Listener listener : listeners) {
+                       listener.logUpdated(this, message);
+               }
+       }
+
+       private void fireSegmenterChanged() {
+               for (Listener listener : listeners) {
+                       listener.segmenterChanged(this);
+               }
+       }
+
+       private void fireForegroundErrorChanged() {
+               for (Listener listener : listeners) {
+                       listener.foregroundErrorChanged(this);
+               }
+       }
+
+       private void fireBackgroundErrorChanged() {
+               for (Listener listener : listeners) {
+                       listener.backgroundErrorChanged(this);
+               }
+       }
+
+       private void fireSegmentationContextChanged() {
+               for (Listener listener : listeners) {
+                       listener.segmentationContextChanged(this);
+               }
+       }
+       
+       public void fireSegmentationContextUpdated() {
+               for (Listener listener : listeners) {
+                       listener.segmentationContextUpdated(this);
+               }
+       }
+       
+       private void fireGroundTruthMaskChanged() {
+               for (Listener listener : listeners) {
+                       listener.groundTruthMaskChanged(this);
+               }
+       }
+       
+       private void fireEvaluationMeasuresChanged() {
+               for (Listener listener : listeners) {
+                       listener.evaluationMeasuresChanged(this);
+               }
+       }
+       
+       private void fireEvaluationResultAdded() {
+               for (Listener listener : listeners) {
+                       listener.evaluationResultsAdded(this);
+               }
+       }
+       
+       private void fireEvaluationResultsCleared() {
+               for (Listener listener : listeners) {
+                       listener.evaluationResultsCleared(this);
+               }
+       }
+       
+       public void fireAutomatorStateChanged() {
+               for (Listener listener : listeners) {
+                       listener.automatorStateChanged(this);
+               }
+       }
+
+       public void addListener(Listener listener) {
+               listeners.add(listener);
+       }
+       
+       public void removeListener(Listener listener) {
+               listeners.remove(listener);
+       }
+}
diff --git a/Annotation/src/ie/dcu/auto/AutomationDataAdapter.class b/Annotation/src/ie/dcu/auto/AutomationDataAdapter.class
new file mode 100644 (file)
index 0000000..2412fd9
Binary files /dev/null and b/Annotation/src/ie/dcu/auto/AutomationDataAdapter.class differ
diff --git a/Annotation/src/ie/dcu/auto/AutomationDataAdapter.java b/Annotation/src/ie/dcu/auto/AutomationDataAdapter.java
new file mode 100644 (file)
index 0000000..6072343
--- /dev/null
@@ -0,0 +1,42 @@
+package ie.dcu.auto;
+
+/**
+ * Convenience class for listeners who are only interested in some events
+ * 
+ * @author Kevin McGuinness
+ */
+public class AutomationDataAdapter implements AutomationData.Listener {
+
+       public void automatorStateChanged(AutomationData data) {
+       }
+
+       public void backgroundErrorChanged(AutomationData data) {
+       }
+
+       public void evaluationMeasuresChanged(AutomationData data) {
+       }
+
+       public void evaluationResultsAdded(AutomationData data) {
+       }
+
+       public void evaluationResultsCleared(AutomationData data) {
+       }
+
+       public void foregroundErrorChanged(AutomationData data) {
+       }
+
+       public void groundTruthMaskChanged(AutomationData data) {
+       }
+
+       public void logUpdated(AutomationData data, String message) {
+       }
+
+       public void segmentationContextChanged(AutomationData data) {
+       }
+
+       public void segmentationContextUpdated(AutomationData automationData) {
+       }
+
+       public void segmenterChanged(AutomationData data) {
+       }
+}
diff --git a/Annotation/src/ie/dcu/auto/AutomationInput.class b/Annotation/src/ie/dcu/auto/AutomationInput.class
new file mode 100644 (file)
index 0000000..917abeb
Binary files /dev/null and b/Annotation/src/ie/dcu/auto/AutomationInput.class differ
diff --git a/Annotation/src/ie/dcu/auto/AutomationInput.java b/Annotation/src/ie/dcu/auto/AutomationInput.java
new file mode 100644 (file)
index 0000000..ccad68e
--- /dev/null
@@ -0,0 +1,102 @@
+package ie.dcu.auto;
+
+import java.io.File;
+
+/**
+ * Immutable class encapsulating an input for the automation.
+ * 
+ * @author Kevin McGuinness
+ */
+public class AutomationInput {
+       
+       /**
+        * The input image file.
+        */
+       public final File imageFile;
+       
+       /**
+        * The input ground-truth mask file.
+        */
+       public final File groundTruthFile;
+       
+       /**
+        * Create an automation input with the given image and ground
+        * truth file.
+        * 
+        * @param imageFile
+        *        The image file (cannot be <code>null</code>).
+        * @param groundTruthFile
+        *        The ground-truth mask file (cannot be <code>null</code>).
+        */
+       public AutomationInput(File imageFile, File groundTruthFile) {
+               
+               if (imageFile == null) {
+                       throw new IllegalArgumentException("imageFile == null");
+               }
+               
+               if (groundTruthFile == null) {
+                       throw new IllegalArgumentException("groundTruthFile == null");
+               }
+               
+               this.imageFile = imageFile;
+               this.groundTruthFile = groundTruthFile;
+       }
+       
+       /**
+        * Returns true if both the image and ground truth files exist.
+        */
+       public boolean filesExist() {
+               return imageFile.isFile() && groundTruthFile.isFile();
+       }
+
+       /**
+        * Returns the image file.
+        */
+       public File getImageFile() {
+               return imageFile;
+       }
+
+       /**
+        * Returns the ground-truth file.
+        */
+       public File getGroundTruthFile() {
+               return groundTruthFile;
+       }
+
+       /**
+        * Returns a deep copy of the object.
+        */
+       @Override
+       protected AutomationInput clone() {
+               return new AutomationInput(imageFile, groundTruthFile);
+       }
+
+       /**
+        * Compare for equality.
+        */
+       @Override
+       public boolean equals(Object obj) {
+               if (obj instanceof AutomationInput) {
+                       AutomationInput x = (AutomationInput) obj;
+                       return x.imageFile.equals(imageFile) && 
+                              x.groundTruthFile.equals(groundTruthFile);
+               }
+               return false;
+       }
+
+       /**
+        * Hash code override.
+        */
+       @Override
+       public int hashCode() {
+               return imageFile.hashCode() + groundTruthFile.hashCode();
+       }
+
+       /**
+        * Returns a string representation
+        */
+       @Override
+       public String toString() {
+               return imageFile.getName() + "," + groundTruthFile.getName();
+       }
+}
diff --git a/Annotation/src/ie/dcu/auto/Constants.class b/Annotation/src/ie/dcu/auto/Constants.class
new file mode 100644 (file)
index 0000000..9019094
Binary files /dev/null and b/Annotation/src/ie/dcu/auto/Constants.class differ
diff --git a/Annotation/src/ie/dcu/auto/Constants.java b/Annotation/src/ie/dcu/auto/Constants.java
new file mode 100644 (file)
index 0000000..2debd37
--- /dev/null
@@ -0,0 +1,5 @@
+package ie.dcu.auto;
+
+public interface Constants {
+       final byte ERROR_VALUE = (byte) 0xff;
+}
diff --git a/Annotation/src/ie/dcu/auto/EvaluationResults$Item.class b/Annotation/src/ie/dcu/auto/EvaluationResults$Item.class
new file mode 100644 (file)
index 0000000..093677d
Binary files /dev/null and b/Annotation/src/ie/dcu/auto/EvaluationResults$Item.class differ
diff --git a/Annotation/src/ie/dcu/auto/EvaluationResults.class b/Annotation/src/ie/dcu/auto/EvaluationResults.class
new file mode 100644 (file)
index 0000000..23618aa
Binary files /dev/null and b/Annotation/src/ie/dcu/auto/EvaluationResults.class differ
diff --git a/Annotation/src/ie/dcu/auto/EvaluationResults.java b/Annotation/src/ie/dcu/auto/EvaluationResults.java
new file mode 100644 (file)
index 0000000..1200990
--- /dev/null
@@ -0,0 +1,66 @@
+package ie.dcu.auto;
+
+import java.util.*;
+
+public class EvaluationResults {
+       
+       private static class Item {
+               final double[] values;
+               
+               public Item(double[] values) {
+                       this.values = values.clone();
+               }
+       };
+       
+       private String[] measures;
+       private final List<Item> results;
+       
+       public EvaluationResults() {
+               this.measures = new String[0];
+               this.results = new ArrayList<Item>();
+       }
+       
+       void setMeasures(String[] measures) {
+               if (this.measures != measures) {
+                       clearResults();
+                       this.measures = measures.clone();
+               }
+       }
+       
+       public String[] getMeasures() {
+               return measures;
+       }
+       
+       public int getMeasureCount() {
+               return measures.length;
+       }
+       
+       public int indexOfMeasure(String measure) {
+               for (int i = 0; i < measures.length; i++) {
+                       if (measures[i].equals(measure)) {
+                               return i;
+                       }
+               }
+               return -1;
+       }
+       
+       void clearResults() {
+               results.clear();
+       }
+
+       void addResults(double[] results) {
+               if (results.length != measures.length) {
+                       throw new IllegalArgumentException();
+               }
+               
+               this.results.add(new Item(results));
+       }
+       
+       public double[] getResults(int idx) {
+               return results.get(idx).values;
+       }
+       
+       public int getResultCount() {
+               return results.size();
+       }       
+}
diff --git a/Annotation/src/ie/dcu/auto/MaximaLocator.class b/Annotation/src/ie/dcu/auto/MaximaLocator.class
new file mode 100644 (file)
index 0000000..884bb80
Binary files /dev/null and b/Annotation/src/ie/dcu/auto/MaximaLocator.class differ
diff --git a/Annotation/src/ie/dcu/auto/MaximaLocator.java b/Annotation/src/ie/dcu/auto/MaximaLocator.java
new file mode 100644 (file)
index 0000000..72fb9c9
--- /dev/null
@@ -0,0 +1,42 @@
+package ie.dcu.auto;
+
+import ie.dcu.matrix.*;
+
+import java.util.*;
+
+public class MaximaLocator {
+
+       private final IntMatrix matrix;
+       private int maximum;
+
+       public MaximaLocator(IntMatrix matrix) {
+               this.matrix = matrix;
+               this.maximum = Integer.MIN_VALUE;
+       }
+       
+       public int getMaximum() {
+               return maximum;
+       }
+       
+       public List<Index2D> findAll(int min) {
+               maximum = matrix.maxValue();
+               
+               if (maximum < min) {
+                       return Collections.emptyList();
+               }
+               
+               List<Index2D> indices = new ArrayList<Index2D>();
+               
+               for (int i = 0; i < matrix.rows; i++) {
+                       int k = i * matrix.cols;
+
+                       for (int j = 0; j < matrix.cols; j++, k++) {
+                               if (matrix.values[k] == maximum) {
+                                       indices.add(new Index2D(i, j));
+                               }
+                       }
+               }
+               
+               return indices;
+       }
+}
diff --git a/Annotation/src/ie/dcu/auto/automator/AbstractAutomator.class b/Annotation/src/ie/dcu/auto/automator/AbstractAutomator.class
new file mode 100644 (file)
index 0000000..b4dbf54
Binary files /dev/null and b/Annotation/src/ie/dcu/auto/automator/AbstractAutomator.class differ
diff --git a/Annotation/src/ie/dcu/auto/automator/AbstractAutomator.java b/Annotation/src/ie/dcu/auto/automator/AbstractAutomator.java
new file mode 100644 (file)
index 0000000..09c8f41
--- /dev/null
@@ -0,0 +1,161 @@
+package ie.dcu.auto.automator;
+
+import ie.dcu.auto.AutomationData;
+import ie.dcu.matrix.*;
+import ie.dcu.segment.*;
+import ie.dcu.segment.annotate.AnnotationManager;
+
+import org.eclipse.swt.graphics.Point;
+
+/**
+ * Handles the grunt work of the automator (maintaining state, sending
+ * notifications, and so forth).
+ * 
+ * Subclasses just need to implement {@link #doReset()}, {@link #doStart()}, and
+ * {@link #doStep()}.
+ * 
+ * 
+ * @author Kevin McGuinness
+ */
+public abstract class AbstractAutomator implements Automator {
+       private final AutomationData data;
+       private boolean done;
+       private int maxSteps;
+       private int step;
+
+       public AbstractAutomator(AutomationData data) {
+               this.data = data;
+               this.done = false;
+               this.maxSteps = DEFAULT_MAX_STEPS;
+               this.step = -1;
+       }
+
+       public void setMaxSteps(int maxSteps) {
+               if (maxSteps < 0) {
+                       throw new IllegalArgumentException();
+               }
+               this.maxSteps = maxSteps;
+       }
+
+       public int getMaxSteps() {
+               return maxSteps;
+       }
+
+       public int getStep() {
+               return step;
+       }
+
+       public boolean canReset() {
+               return hasSegmentationContext();
+       }
+
+       public boolean canStart() {
+               return step == 0 && hasSegmentationContext();
+       }
+
+       public boolean canStep() {
+               return step > 0 && !done && hasSegmentationContext() && step < maxSteps;
+       }
+
+       public void reset() {
+               if (canReset()) {
+                       doReset();
+                       getSegmenter().finish(getSegmentationContext());
+                       getAnnotations().clear();
+                       getSegmentationContext().getMask().clear();
+                       getSegmenter().init(getSegmentationContext());
+                       step = 0;
+                       done = false;
+                       data.clearEvaluationResults();
+                       data.updateSegmentationError();
+                       data.fireAutomatorStateChanged();
+                       data.fireSegmentationContextUpdated();
+               }
+       }
+
+       public void start() {
+               if (canStart()) {
+                       doStart();
+
+                       // Update segmentation
+                       getSegmenter().update(getSegmentationContext());
+
+                       // Evaluate
+                       data.evaluate();
+
+                       // Set step
+                       step = 1;
+
+                       // Notify
+                       data.updateSegmentationError();
+                       data.fireAutomatorStateChanged();
+                       data.fireSegmentationContextUpdated();
+               }
+       }
+
+       public void step() {
+               if (canStep()) {
+                       doStep();
+
+                       // Update segmentation
+                       getSegmenter().update(getSegmentationContext());
+
+                       // Evaluate
+                       data.evaluate();
+
+                       // Increment step
+                       step++;
+
+                       if (done || step == maxSteps) {
+                               getSegmenter().finish(getSegmentationContext());
+                       }
+
+                       // Notify
+                       data.updateSegmentationError();
+                       data.fireAutomatorStateChanged();
+                       data.fireSegmentationContextUpdated();
+               }
+       }
+
+       private boolean hasSegmentationContext() {
+               return data.getSegmentationContext() != null;
+       }
+
+       private Segmenter getSegmenter() {
+               return data.getSegmenter();
+       }
+
+       private SegmentationContext getSegmentationContext() {
+               return data.getSegmentationContext();
+       }
+
+       protected AnnotationManager getAnnotations() {
+               return data.getSegmentationContext().getAnnotations();
+       }
+
+       protected ByteMatrix getForegroundError() {
+               return data.getForegroundError();
+       }
+
+       protected ByteMatrix getBackgroundError() {
+               return data.getBackgroundError();
+       }
+
+       protected void log(String format, Object... args) {
+               data.logActivity(String.format(format, args));
+       }
+
+       protected void setDone(boolean done) {
+               this.done = done;
+       }
+
+       protected static Point getSwtPointForIndex(Index2D index) {
+               return new Point(index.j, index.i);
+       }
+
+       protected abstract void doReset();
+
+       protected abstract void doStart();
+
+       protected abstract void doStep();
+}
diff --git a/Annotation/src/ie/dcu/auto/automator/Automator.class b/Annotation/src/ie/dcu/auto/automator/Automator.class
new file mode 100644 (file)
index 0000000..eca6f16
Binary files /dev/null and b/Annotation/src/ie/dcu/auto/automator/Automator.class differ
diff --git a/Annotation/src/ie/dcu/auto/automator/Automator.java b/Annotation/src/ie/dcu/auto/automator/Automator.java
new file mode 100644 (file)
index 0000000..aba621b
--- /dev/null
@@ -0,0 +1,64 @@
+package ie.dcu.auto.automator;
+
+/**
+ * Automates the evaluation of interactive segmentation algorithms
+ * 
+ * @author Kevin McGuinness
+ */
+public interface Automator {
+
+       /**
+        * The maximum brush size that an automator may use.
+        */
+       public static final int MAX_BRUSH_SIZE = 20;
+       
+       /**
+        * The default maximum number of steps to use.
+        */
+       public static final int DEFAULT_MAX_STEPS = 200;
+
+       /**
+        * Returns the current step.
+        */
+       public int getStep();
+
+       /**
+        * Returns the max number of steps the automator will take.
+        */
+       public int getMaxSteps();
+
+       /**
+        * Set the max number of steps the automator will take.
+        */
+       public void setMaxSteps(int maxSteps);
+
+       /**
+        * Returns true if the automator can currently be reset.
+        */
+       public boolean canReset();
+
+       /**
+        * Reset the automator.
+        */
+       public void reset();
+
+       /**
+        * Returns true if the automator can currently be started.
+        */
+       public boolean canStart();
+
+       /**
+        * Start the automator.
+        */
+       public void start();
+
+       /**
+        * Returns true if a step in the automation can be taken.
+        */
+       public boolean canStep();
+
+       /**
+        * Take the next step in the automation procedure.
+        */
+       public void step();
+}
\ No newline at end of file
diff --git a/Annotation/src/ie/dcu/auto/automator/AutomatorFactory.class b/Annotation/src/ie/dcu/auto/automator/AutomatorFactory.class
new file mode 100644 (file)
index 0000000..a397f6a
Binary files /dev/null and b/Annotation/src/ie/dcu/auto/automator/AutomatorFactory.class differ
diff --git a/Annotation/src/ie/dcu/auto/automator/AutomatorFactory.java b/Annotation/src/ie/dcu/auto/automator/AutomatorFactory.java
new file mode 100644 (file)
index 0000000..8798af1
--- /dev/null
@@ -0,0 +1,91 @@
+package ie.dcu.auto.automator;
+
+import ie.dcu.auto.AutomationData;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+/**
+ * Creates automator instances.
+ * 
+ * @author Kevin McGuinness
+ */
+public class AutomatorFactory {
+       
+       public static final String STRATEGY1 = "Strategy 1 (Deterministic)";
+       public static final String STRATEGY2 = "Strategy 2 (Probabilistic)";
+       public static final String STRATEGY3 = "Strategy 3 (Probabilistic)";
+       public static final String STRATEGY4 = "Strategy 4 (Probabilistic)";
+       
+       private final Map<String, Class<? extends Automator>> automators;
+       private static AutomatorFactory instance;
+       
+       private AutomatorFactory() {
+               automators = new HashMap<String, Class<? extends Automator>>();
+               automators.put(STRATEGY1, DeterministicAutomator.class);
+               automators.put(STRATEGY2, NonDeterministicAutomator1.class);
+               automators.put(STRATEGY3, NonDeterministicAutomator2.class);
+               automators.put(STRATEGY4, NonDeterministicAutomator3.class);
+       }
+       
+       public Automator createAutomator(String strategy, AutomationData data) {
+               
+               try {
+                       Class<? extends Automator> clazz = automators.get(strategy);
+                       if (clazz != null) {
+                               Constructor<? extends Automator> ctor = 
+                                       clazz.getConstructor(AutomationData.class);
+                               return ctor.newInstance(data);
+                       } else {
+                               throw new IllegalArgumentException(
+                                       "no such strategy: " + strategy);
+                       }
+                       
+               } catch (SecurityException e) {
+                       throw new RuntimeException(e);
+               } catch (NoSuchMethodException e) {
+                       throw new RuntimeException(e);
+               } catch (InstantiationException e) {
+                       throw new RuntimeException(e);
+               } catch (IllegalAccessException e) {
+                       throw new RuntimeException(e);
+               } catch (InvocationTargetException e) {
+                       throw new RuntimeException(e);
+               }
+       }
+       
+       public boolean hasAutomator(String strategy) {
+               return automators.containsKey(strategy);
+       }
+       
+       public Set<String> getAvailableStrategies() {
+               return Collections.unmodifiableSet(automators.keySet());
+       }       
+       
+       public boolean isNonDeterministic(String strategy) {
+               if (hasAutomator(strategy)) {
+                       Class<? extends Automator> clazz = automators.get(strategy);
+                       try {
+                               Method method = clazz.getMethod("isNonDeterministic");
+                               return (Boolean) method.invoke(null);
+
+                       } catch (SecurityException e) {
+                               return false;
+                       } catch (NoSuchMethodException e) {
+                               return false;
+                       } catch (IllegalAccessException e) {
+                               throw new RuntimeException(e);
+                       } catch (InvocationTargetException e) {
+                               throw new RuntimeException(e);
+                       }
+               }
+               return false;
+       }
+       
+       public static AutomatorFactory getInstance() {
+               if (instance == null) {
+                       instance = new AutomatorFactory();
+               }
+               return instance;
+       }
+}
diff --git a/Annotation/src/ie/dcu/auto/automator/DeterministicAutomator.class b/Annotation/src/ie/dcu/auto/automator/DeterministicAutomator.class
new file mode 100644 (file)
index 0000000..5319361
Binary files /dev/null and b/Annotation/src/ie/dcu/auto/automator/DeterministicAutomator.class differ
diff --git a/Annotation/src/ie/dcu/auto/automator/DeterministicAutomator.java b/Annotation/src/ie/dcu/auto/automator/DeterministicAutomator.java
new file mode 100644 (file)
index 0000000..8270381
--- /dev/null
@@ -0,0 +1,156 @@
+package ie.dcu.auto.automator;
+
+import ie.dcu.auto.*;
+import ie.dcu.image.dt.DistanceTransform;
+import ie.dcu.matrix.*;
+import ie.dcu.segment.annotate.*;
+
+import java.util.*;
+
+import org.eclipse.swt.graphics.Point;
+
+/**
+ * Automates the evaluation of interactive segmentation algorithms using 
+ * a simple deterministic method.
+ * 
+ * @author Kevin McGuinness
+ */
+public class DeterministicAutomator extends AbstractAutomator implements Automator {
+       private final Set<Index2D> seeds;
+
+       public DeterministicAutomator(AutomationData data) {
+               super(data);
+               this.seeds = new HashSet<Index2D>();
+       }
+       
+       protected void doReset() {
+               seeds.clear();
+       }
+       
+       protected void doStart() {
+               
+               // Get error
+               ByteMatrix fgError = getForegroundError();
+               ByteMatrix bgError = getBackgroundError();
+               
+               // DT
+               IntMatrix fgDT = distanceTransform(fgError);
+               IntMatrix bgDT = distanceTransform(bgError);
+               
+               // Maxima
+               MaximaLocator fgLocator = new MaximaLocator(fgDT);
+               List<Index2D> fgMaxima = fgLocator.findAll(2);
+               
+               MaximaLocator bgLocator = new MaximaLocator(bgDT);
+               List<Index2D> bgMaxima = bgLocator.findAll(2);
+               
+               // Add seeds
+               if (fgMaxima.size() > 0 && bgMaxima.size() > 0) {
+                       addForegroundSeeds(fgMaxima, fgLocator.getMaximum());
+                       addBackgroundSeeds(bgMaxima, bgLocator.getMaximum());
+               } else if (fgMaxima.size() > 0) {
+                       addForegroundSeeds(fgMaxima, fgLocator.getMaximum());
+               } else if (bgMaxima.size() > 0) {
+                       addBackgroundSeeds(bgMaxima, bgLocator.getMaximum());
+               } else {
+                       log("Automation complete");
+                       setDone(true);
+               }
+       }
+       
+       protected void doStep() {
+               
+               // Get error
+               ByteMatrix fgError = getForegroundError();
+               ByteMatrix bgError = getBackgroundError();
+               
+               // DT
+               IntMatrix fgDT = distanceTransform(fgError);
+               IntMatrix bgDT = distanceTransform(bgError);
+               
+               // Maxima
+               MaximaLocator fgLocator = new MaximaLocator(fgDT);
+               List<Index2D> fgMaxima = fgLocator.findAll(2);
+               
+               MaximaLocator bgLocator = new MaximaLocator(bgDT);
+               List<Index2D> bgMaxima = bgLocator.findAll(2);
+               
+               log("Found %d potential foreground seeds", fgMaxima.size());
+               log("Found %d potential background seeds", bgMaxima.size());
+               
+               // Remove previously selected seeds
+               removeSelectedSeeds(fgMaxima);
+               removeSelectedSeeds(bgMaxima);
+               
+               // Add seeds
+               if (fgMaxima.size() > 0 && bgMaxima.size() > 0) {
+                       
+                       if (fgLocator.getMaximum() >= bgLocator.getMaximum()) {
+                               addForegroundSeeds(fgMaxima, fgLocator.getMaximum());   
+                       } else {
+                               addBackgroundSeeds(bgMaxima, bgLocator.getMaximum());
+                       }
+                       
+               } else if (fgMaxima.size() > 0) {               
+                       addForegroundSeeds(fgMaxima, fgLocator.getMaximum());
+                       
+               } else if (bgMaxima.size() > 0) {
+                       addBackgroundSeeds(bgMaxima, bgLocator.getMaximum());
+                       
+               } else {
+                       log("Automation complete");
+                       setDone(true);
+               }
+       }
+
+       private void removeSelectedSeeds(List<Index2D> seeds) {
+               Iterator<Index2D> iterator = seeds.iterator();
+               
+               while (iterator.hasNext()) {
+                       Index2D seed = iterator.next();
+                       if (this.seeds.contains(seed)) {
+                               iterator.remove();
+                       } 
+               }
+       }
+
+       private void addBackgroundSeeds(List<Index2D> seeds, int maximum) {
+               double distance = Math.sqrt(maximum);
+               
+               log("Adding %d background seeds (distance: %f)", seeds.size(), distance);
+               
+               int size = (int) Math.min(distance/2, MAX_BRUSH_SIZE);
+               
+               AnnotationManager annotations = getAnnotations();
+               for (Index2D seed : seeds) {
+                       this.seeds.add(seed);
+                       Point pt = getSwtPointForIndex(seed);
+                       annotations.add(new Annotation(AnnotationType.Background, size, pt));
+               }
+       }
+
+       private void addForegroundSeeds(List<Index2D> seeds, int maximum) {
+               double distance = Math.sqrt(maximum);
+               
+               log("Adding %d foreground seeds (distance: %f)", seeds.size(), distance);
+               
+               int size = (int) Math.min(distance/2, MAX_BRUSH_SIZE);
+               
+               AnnotationManager annotations = getAnnotations();
+               for (Index2D seed : seeds) {
+                       this.seeds.add(seed);
+                       Point pt = getSwtPointForIndex(seed);
+                       annotations.add(new Annotation(AnnotationType.Foreground, size, pt));
+               }
+       }
+
+       private static IntMatrix distanceTransform(ByteMatrix error) {
+               DistanceTransform dt = new DistanceTransform();
+               dt.init(error, Constants.ERROR_VALUE);
+               return dt.computeSquareTransform();
+       }
+       
+       public static boolean isNonDeterministic() {
+               return false;
+       }
+}
diff --git a/Annotation/src/ie/dcu/auto/automator/NonDeterministicAutomator1.class b/Annotation/src/ie/dcu/auto/automator/NonDeterministicAutomator1.class
new file mode 100644 (file)
index 0000000..b689c7f
Binary files /dev/null and b/Annotation/src/ie/dcu/auto/automator/NonDeterministicAutomator1.class differ
diff --git a/Annotation/src/ie/dcu/auto/automator/NonDeterministicAutomator1.java b/Annotation/src/ie/dcu/auto/automator/NonDeterministicAutomator1.java
new file mode 100644 (file)
index 0000000..530f935
--- /dev/null
@@ -0,0 +1,141 @@
+package ie.dcu.auto.automator;
+
+import ie.dcu.auto.*;
+import ie.dcu.image.dt.DistanceTransform;
+import ie.dcu.matrix.*;
+import ie.dcu.segment.annotate.*;
+import ie.dcu.stats.InversionMethod;
+
+import java.util.*;
+
+import org.eclipse.swt.graphics.Point;
+
+/**
+ * Automates the evaluation of interactive segmentation algorithms using 
+ * a simple non-deterministic method.
+ * 
+ * @author Kevin McGuinness
+ */
+public class NonDeterministicAutomator1 
+       extends AbstractAutomator implements Automator 
+{
+       private final Set<Index2D> seeds;
+
+       public NonDeterministicAutomator1(AutomationData data) {
+               super(data);
+               this.seeds = new HashSet<Index2D>();
+       }
+       
+       protected void doReset() {
+               seeds.clear();
+       }
+       
+       protected void doStart() {
+               
+               // Distance transform
+               DoubleMatrix fgDT = distanceTransform(getForegroundError());
+               DoubleMatrix bgDT = distanceTransform(getBackgroundError());
+               
+               // Initialize foreground probability field
+               Index2D fgIndex = null;
+               if (nonzero(fgDT)) {
+                       InversionMethod fgProb = new InversionMethod(fgDT.values);
+                       fgIndex = fgDT.indexOf(fgProb.random());
+               }
+               
+               // Initialize background probability field
+               Index2D bgIndex = null;
+               if (nonzero(bgDT)) {
+                       InversionMethod bgProb = new InversionMethod(bgDT.values);
+                       bgIndex = bgDT.indexOf(bgProb.random());
+               }
+               
+               // Add seeds
+               if (fgIndex != null && bgIndex != null) {
+                       addSeed(fgDT, fgIndex, AnnotationType.Foreground);
+                       addSeed(bgDT, bgIndex, AnnotationType.Background);
+               } else if (fgIndex != null) {
+                       addSeed(fgDT, fgIndex, AnnotationType.Foreground);
+               } else if (bgIndex != null) {
+                       addSeed(bgDT, bgIndex, AnnotationType.Background);
+               } else {
+                       log("Automation complete");
+                       setDone(true);
+               }
+       }
+
+       protected void doStep() {
+               ByteMatrix fgError = getForegroundError();
+               ByteMatrix bgError = getBackgroundError();
+               
+               DoubleMatrix field = getProbabilityField(fgError, bgError);
+               if (field != null) {
+                       InversionMethod rv = new InversionMethod(field.values);
+                       Index2D seed = field.indexOf(rv.random());
+                       AnnotationType type = 
+                               (fgError.byteAt(seed) == Constants.ERROR_VALUE) ?
+                               AnnotationType.Foreground : AnnotationType.Background;
+                       addSeed(field, seed, type);
+                       
+               } else {
+                       log("Automation complete");
+                       setDone(true);
+               }
+       }
+       
+       private DoubleMatrix getProbabilityField(ByteMatrix fgError, ByteMatrix bgError) {
+               
+               // Distance transforms
+               DoubleMatrix fgDT = distanceTransform(fgError);
+               DoubleMatrix bgDT = distanceTransform(bgError);
+               
+               // Sum transforms
+               DoubleMatrix field = fgDT;
+               for (int i = 0; i < field.size; i++) {
+                       field.values[i] += bgDT.values[i];
+               }
+               
+               // Set probability of selected seeds to zero
+               for (Index2D seed : seeds) {
+                       field.setDoubleAt(seed, 0.0);
+               }
+               
+               if (!isStoppingCriteriaSatisfied(field)) {
+                       return field;
+               }
+               
+               return null;
+       }
+       
+       private void addSeed(DoubleMatrix dt, Index2D seed, AnnotationType type) {
+               double distance = dt.doubleAt(seed);
+               int size = (int) Math.min(distance/2, MAX_BRUSH_SIZE);
+               size = Math.max(size, 1);
+               Point pt = getSwtPointForIndex(seed);
+               getAnnotations().add(new Annotation(type, size, pt));
+               seeds.add(seed);
+       }
+
+       private static DoubleMatrix distanceTransform(ByteMatrix error) {
+               DistanceTransform dt = new DistanceTransform();
+               dt.init(error, Constants.ERROR_VALUE);
+               return dt.computeTransform();
+       }
+       
+       private static boolean isStoppingCriteriaSatisfied(DoubleMatrix dt) {
+               return dt.maxValue() < 2.0;
+       }
+       
+       private static boolean nonzero(DoubleMatrix matrix) {
+               for (int i = 0; i < matrix.size; i++) {
+                       if (matrix.values[i] != 0) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+       
+       public static boolean isNonDeterministic() {
+               return true;
+       }
+}
diff --git a/Annotation/src/ie/dcu/auto/automator/NonDeterministicAutomator2.class b/Annotation/src/ie/dcu/auto/automator/NonDeterministicAutomator2.class
new file mode 100644 (file)
index 0000000..2027b28
Binary files /dev/null and b/Annotation/src/ie/dcu/auto/automator/NonDeterministicAutomator2.class differ
diff --git a/Annotation/src/ie/dcu/auto/automator/NonDeterministicAutomator2.java b/Annotation/src/ie/dcu/auto/automator/NonDeterministicAutomator2.java
new file mode 100644 (file)
index 0000000..161d33f
--- /dev/null
@@ -0,0 +1,295 @@
+package ie.dcu.auto.automator;
+
+import static ie.dcu.auto.Constants.ERROR_VALUE;
+import ie.dcu.auto.*;
+import ie.dcu.graph.dijkstra.IntGraph;
+import ie.dcu.image.dt.DistanceTransform;
+import ie.dcu.matrix.*;
+import ie.dcu.segment.annotate.*;
+import ie.dcu.stats.InversionMethod;
+
+import java.util.*;
+
+import org.eclipse.swt.graphics.Point;
+
+/**
+ * Implementation of the more complex non-deterministic strategy for interactive
+ * segmentation evaluation.
+ * 
+ * @author Kevin McGuinness
+ * 
+ */
+public class NonDeterministicAutomator2 
+       extends AbstractAutomator implements Automator 
+{
+       private final Set<Index2D> seeds;
+       
+       public NonDeterministicAutomator2(AutomationData data) {
+               super(data);
+               this.seeds = new HashSet<Index2D>();
+       }
+
+       @Override
+       protected void doReset() {
+               seeds.clear();
+       }
+
+       @Override
+       protected void doStart() {
+               ByteMatrix fgError = getForegroundError();
+               ByteMatrix bgError = getBackgroundError();
+
+               // Distance transform
+               DoubleMatrix fgDT = distanceTransform(fgError);
+               DoubleMatrix bgDT = distanceTransform(bgError);
+               
+               // Initialize foreground probability field
+               List<Integer> fgPath = createPath(fgError, fgDT);
+               List<Integer> bgPath = createPath(bgError, bgDT);
+               
+               // Add seeds
+               if (fgPath != null && bgPath != null) {
+                       addSeedPath(fgDT, fgPath, AnnotationType.Foreground);
+                       addSeedPath(bgDT, bgPath, AnnotationType.Background);
+               } else if (fgPath != null) {
+                       addSeedPath(fgDT, fgPath, AnnotationType.Foreground);
+               } else if (bgPath != null) {
+                       addSeedPath(bgDT, bgPath, AnnotationType.Background);
+               } else {
+                       log("Automation complete");
+                       setDone(true);
+               }
+       }
+
+       @Override
+       protected void doStep() {
+               ByteMatrix fgError = getForegroundError();
+               ByteMatrix bgError = getBackgroundError();
+               
+               DoubleMatrix fgDT = distanceTransform(fgError);
+               DoubleMatrix bgDT = distanceTransform(bgError);
+               
+               DoubleMatrix field = getProbabilityField(fgDT, bgDT);
+               
+               if (field != null) {
+                       InversionMethod rv = new InversionMethod(field.values);
+                       int seed = rv.random();
+                       List<Integer> path = null;
+                       AnnotationType type;
+                       
+                       if (fgError.values[seed] == ERROR_VALUE) {
+                               type = AnnotationType.Foreground;
+                               path = createPath(fgError, fgDT, seed);
+                       
+                       } else {
+                               type = AnnotationType.Background;
+                               path = createPath(bgError, bgDT, seed); 
+                       }
+                       
+                       if (path != null) {
+                               addSeedPath(field, path, type);
+                       } else {
+                               addSeed(field, seed, type);
+                       }
+                       
+               } else {
+                       log("Automation complete");
+                       setDone(true);
+               }
+       }
+
+       private void addSeed(DoubleMatrix field, int seed, AnnotationType type) {
+               log("Adding single seed");
+               
+               Index2D index = field.indexOf(seed);
+               double distance = field.doubleAt(seed);
+               int size = (int) Math.min(distance/2, MAX_BRUSH_SIZE);
+               size = Math.max(size, 1);
+               Point pt = getSwtPointForIndex(index);
+               getAnnotations().add(new Annotation(type, size, pt));
+               seeds.add(index);
+       }
+
+       private void addSeedPath(
+               DoubleMatrix field, List<Integer> path, AnnotationType type) {
+               
+               log("Adding seed path");
+               
+               int size = MAX_BRUSH_SIZE;
+               for (int k : path) {
+                       double distance = field.doubleAt(k);
+                       size = (int) Math.min(size, distance/2);
+               }
+               
+               size = Math.max(size, 1);
+               
+               for (int k : path) {
+                       Index2D index = field.indexOf(k);
+                       Point pt = getSwtPointForIndex(index);
+                       getAnnotations().add(new Annotation(type, size, pt));
+                       seeds.add(index);
+               }
+       }
+
+       private List<Integer> createPath(ByteMatrix error, DoubleMatrix dt) {
+               if (nonzero(dt)) {
+                       
+                       // Select random variable
+                       InversionMethod field = new InversionMethod(dt.values);
+                       int source = field.random();
+                       
+                       // Create path
+                       return createPath(error, dt, source);
+               }
+               
+               return null;
+       }
+
+       private List<Integer> createPath(ByteMatrix error, DoubleMatrix dt, int source) {
+               
+               // Build graph
+               IntGraph graph = buildGraph(error);
+               
+               // The graph may not contain the source pixel if it has no neighbors
+               if (graph.hasNode(source)) {
+                       
+                       // Ok, it does
+                       graph.findPaths(source);
+                       
+                       // Mark inaccessible pixels with probability zero
+                       for (int i = 0; i < dt.size; i++) {
+                               if (!graph.hasNode(i)) {
+                                       dt.values[i] = 0.0;
+                               }
+                       }
+                       
+                       if (nonzero(dt)) {
+                               
+                               // Select random variable
+                               InversionMethod field = new InversionMethod(dt.values);
+                               int target = field.random();
+                               
+                               // Get shortest path
+                               return graph.getPathFrom(target);
+                       }
+               } 
+               
+               return null;
+       }
+       
+       private DoubleMatrix getProbabilityField(
+               DoubleMatrix fgDT, DoubleMatrix bgDT) {
+               
+               // Sum transforms
+               DoubleMatrix field = fgDT.clone();
+               for (int i = 0; i < field.size; i++) {
+                       field.values[i] += bgDT.values[i];
+               }
+               
+               // Set probability of selected seeds to zero
+               for (Index2D seed : seeds) {
+                       field.setDoubleAt(seed, 0.0);
+               }
+               
+               if (!isStoppingCriteriaSatisfied(field)) {
+                       return field;
+               }
+               
+               return null;
+       }
+       
+       private static IntGraph buildGraph(ByteMatrix matrix) {
+               
+               final double SQRT_2 = Math.sqrt(2.0);
+               final byte[] values = matrix.values;
+               final int rows = matrix.rows;
+               final int cols = matrix.cols;
+               final IntGraph graph = new IntGraph(matrix.size);
+               
+               for (int i = 0; i < rows; i++) {
+                       int k = i * cols;
+
+                       for (int j = 0; j < cols; j++, k++) {
+                               if (values[k] != ERROR_VALUE) {
+                                       continue;
+                               }
+                               
+                               // Locations neighboring pixels
+                               final int north = k - cols;
+                               final int south = k + cols;
+                               final int west  = k - 1;
+                               final int east  = k + 1;
+                               final int northWest = north - 1;
+                               final int northEast = north + 1;
+                               final int southWest = south - 1;
+                               final int southEast = south + 1;
+                               
+                               final boolean hasNorth = i > 0;
+                               final boolean hasSouth = i + 1 < rows;
+                               final boolean hasWest  = j > 0;
+                               final boolean hasEast  = j + 1 < cols;
+                               
+                               if (hasNorth) {
+                                       if (hasWest && values[northWest] == ERROR_VALUE) {
+                                               graph.addDirectedEdge(k, northWest, SQRT_2);
+                                       }
+                                       
+                                       if (values[north] == ERROR_VALUE) {
+                                               graph.addDirectedEdge(k, north, 1.0);
+                                       }
+                               
+                                       if (hasEast && values[northEast] == ERROR_VALUE) {
+                                               graph.addDirectedEdge(k, northEast, SQRT_2);
+                                       }
+                               }
+                               
+                               if (hasWest && values[west] == ERROR_VALUE) {
+                                       graph.addDirectedEdge(k, west, 1.0);
+                               }
+                               
+                               if (hasEast && values[east] == ERROR_VALUE) {
+                                       graph.addDirectedEdge(k, east, 1.0);
+                               }
+                               
+                               if (hasSouth) {
+                                       if (hasWest && values[southWest] == ERROR_VALUE) {
+                                               graph.addDirectedEdge(k, southWest, SQRT_2);
+                                       }
+                                       
+                                       if (values[south] == ERROR_VALUE) {
+                                               graph.addDirectedEdge(k, south, 1.0);
+                                       }
+                                       
+                                       if (hasEast && values[southEast] == ERROR_VALUE) {
+                                               graph.addDirectedEdge(k, southEast, SQRT_2);
+                                       }
+                               }
+                       }
+               }
+               
+               return graph;
+       }
+
+       private static DoubleMatrix distanceTransform(ByteMatrix error) {
+               DistanceTransform dt = new DistanceTransform();
+               dt.init(error, Constants.ERROR_VALUE);
+               return dt.computeTransform();
+       }
+       
+       private static boolean isStoppingCriteriaSatisfied(DoubleMatrix dt) {
+               return dt.maxValue() < 2.0;
+       }
+       
+       private static boolean nonzero(DoubleMatrix matrix) {
+               for (int i = 0; i < matrix.size; i++) {
+                       if (matrix.values[i] != 0) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+       
+       public static boolean isNonDeterministic() {
+               return true;
+       }
+}
diff --git a/Annotation/src/ie/dcu/auto/automator/NonDeterministicAutomator3.class b/Annotation/src/ie/dcu/auto/automator/NonDeterministicAutomator3.class
new file mode 100644 (file)
index 0000000..3120d9b
Binary files /dev/null and b/Annotation/src/ie/dcu/auto/automator/NonDeterministicAutomator3.class differ
diff --git a/Annotation/src/ie/dcu/auto/automator/NonDeterministicAutomator3.java b/Annotation/src/ie/dcu/auto/automator/NonDeterministicAutomator3.java
new file mode 100644 (file)
index 0000000..b1f8980
--- /dev/null
@@ -0,0 +1,312 @@
+package ie.dcu.auto.automator;
+
+import static ie.dcu.auto.Constants.ERROR_VALUE;
+import ie.dcu.auto.*;
+import ie.dcu.graph.dijkstra.IntGraph;
+import ie.dcu.image.dt.DistanceTransform;
+import ie.dcu.matrix.*;
+import ie.dcu.segment.annotate.*;
+import ie.dcu.stats.InversionMethod;
+
+import java.util.*;
+
+import org.eclipse.swt.graphics.Point;
+
+/**
+ * Implementation of the more complex non-deterministic strategy for interactive
+ * segmentation evaluation. This automator weights the pixels so that the paths
+ * found tend to stay closer to the center of the shape, rather than using the
+ * absolute shortest path
+ * 
+ * @author Kevin McGuinness
+ * 
+ */
+public class NonDeterministicAutomator3 
+       extends AbstractAutomator implements Automator 
+{
+       private final Set<Index2D> seeds;
+       
+       public NonDeterministicAutomator3(AutomationData data) {
+               super(data);
+               this.seeds = new HashSet<Index2D>();
+       }
+
+       @Override
+       protected void doReset() {
+               seeds.clear();
+       }
+
+       @Override
+       protected void doStart() {
+               ByteMatrix fgError = getForegroundError();
+               ByteMatrix bgError = getBackgroundError();
+
+               // Distance transform
+               DoubleMatrix fgDT = distanceTransform(fgError);
+               DoubleMatrix bgDT = distanceTransform(bgError);
+               
+               // Initialize foreground probability field
+               List<Integer> fgPath = createPath(fgError, fgDT);
+               List<Integer> bgPath = createPath(bgError, bgDT);
+               
+               // Add seeds
+               if (fgPath != null && bgPath != null) {
+                       addSeedPath(fgDT, fgPath, AnnotationType.Foreground);
+                       addSeedPath(bgDT, bgPath, AnnotationType.Background);
+               } else if (fgPath != null) {
+                       addSeedPath(fgDT, fgPath, AnnotationType.Foreground);
+               } else if (bgPath != null) {
+                       addSeedPath(bgDT, bgPath, AnnotationType.Background);
+               } else {
+                       log("Automation complete");
+                       setDone(true);
+               }
+       }
+
+       @Override
+       protected void doStep() {
+               ByteMatrix fgError = getForegroundError();
+               ByteMatrix bgError = getBackgroundError();
+               
+               DoubleMatrix fgDT = distanceTransform(fgError);
+               DoubleMatrix bgDT = distanceTransform(bgError);
+               
+               DoubleMatrix field = getProbabilityField(fgDT, bgDT);
+               
+               if (field != null) {
+                       InversionMethod rv = new InversionMethod(field.values);
+                       int seed = rv.random();
+                       List<Integer> path = null;
+                       AnnotationType type;
+                       
+                       if (fgError.values[seed] == ERROR_VALUE) {
+                               type = AnnotationType.Foreground;
+                               path = createPath(fgError, fgDT, seed);
+                       
+                       } else {
+                               type = AnnotationType.Background;
+                               path = createPath(bgError, bgDT, seed); 
+                       }
+                       
+                       if (path != null) {
+                               addSeedPath(field, path, type);
+                       } else {
+                               addSeed(field, seed, type);
+                       }
+                       
+               } else {
+                       log("Automation complete");
+                       setDone(true);
+               }
+       }
+
+       private void addSeed(DoubleMatrix field, int seed, AnnotationType type) {
+               log("Adding single seed");
+               
+               Index2D index = field.indexOf(seed);
+               double distance = field.doubleAt(seed);
+               int size = (int) Math.min(distance/2, MAX_BRUSH_SIZE);
+               size = Math.max(size, 1);
+               Point pt = getSwtPointForIndex(index);
+               getAnnotations().add(new Annotation(type, size, pt));
+               seeds.add(index);
+       }
+
+       private void addSeedPath(
+               DoubleMatrix field, List<Integer> path, AnnotationType type) {
+               
+               log("Adding seed path");
+               
+               int size = MAX_BRUSH_SIZE;
+               for (int k : path) {
+                       double distance = field.doubleAt(k);
+                       size = (int) Math.min(size, distance/2);
+               }
+               
+               size = Math.max(size, 1);
+               
+               for (int k : path) {
+                       Index2D index = field.indexOf(k);
+                       Point pt = getSwtPointForIndex(index);
+                       getAnnotations().add(new Annotation(type, size, pt));
+                       seeds.add(index);
+               }
+       }
+
+       private List<Integer> createPath(ByteMatrix error, DoubleMatrix dt) {
+               if (nonzero(dt)) {
+                       
+                       // Select random variable
+                       InversionMethod field = new InversionMethod(dt.values);
+                       int source = field.random();
+                       
+                       // Create path
+                       return createPath(error, dt, source);
+               }
+               
+               return null;
+       }
+
+       private List<Integer> createPath(ByteMatrix error, DoubleMatrix dt, int source) {
+               
+               // Build graph
+               IntGraph graph = buildGraph(error, dt);
+               
+               // The graph may not contain the source pixel if it has no neighbors
+               if (graph.hasNode(source)) {
+                       
+                       // Ok, it does
+                       graph.findPaths(source);
+                       
+                       // Mark inaccessible pixels with probability zero
+                       for (int i = 0; i < dt.size; i++) {
+                               if (!graph.hasNode(i)) {
+                                       dt.values[i] = 0.0;
+                               }
+                       }
+                       
+                       if (nonzero(dt)) {
+                               
+                               // Select random variable
+                               InversionMethod field = new InversionMethod(dt.values);
+                               int target = field.random();
+                               
+                               // Get shortest path
+                               return graph.getPathFrom(target);
+                       }
+               } 
+               
+               return null;
+       }
+       
+       private DoubleMatrix getProbabilityField(
+               DoubleMatrix fgDT, DoubleMatrix bgDT) {
+               
+               // Sum transforms
+               DoubleMatrix field = fgDT.clone();
+               for (int i = 0; i < field.size; i++) {
+                       field.values[i] += bgDT.values[i];
+               }
+               
+               // Set probability of selected seeds to zero
+               for (Index2D seed : seeds) {
+                       field.setDoubleAt(seed, 0.0);
+               }
+               
+               if (!isStoppingCriteriaSatisfied(field)) {
+                       return field;
+               }
+               
+               return null;
+       }
+       
+       private static IntGraph buildGraph(ByteMatrix matrix, DoubleMatrix dt) {
+               
+               final double dtmax = dt.maxValue();
+               final double SQRT_2 = Math.sqrt(2.0);
+               final byte[] values = matrix.values;
+               final int rows = matrix.rows;
+               final int cols = matrix.cols;
+               final IntGraph graph = new IntGraph(matrix.size);
+               
+               for (int i = 0; i < rows; i++) {
+                       int k = i * cols;
+
+                       for (int j = 0; j < cols; j++, k++) {
+                               if (values[k] != ERROR_VALUE) {
+                                       continue;
+                               }
+                               
+                               // Locations neighboring pixels
+                               final int north = k - cols;
+                               final int south = k + cols;
+                               final int west  = k - 1;
+                               final int east  = k + 1;
+                               final int northWest = north - 1;
+                               final int northEast = north + 1;
+                               final int southWest = south - 1;
+                               final int southEast = south + 1;
+                               
+                               final boolean hasNorth = i > 0;
+                               final boolean hasSouth = i + 1 < rows;
+                               final boolean hasWest  = j > 0;
+                               final boolean hasEast  = j + 1 < cols;
+                               
+                               double w;
+                               
+                               if (hasNorth) {
+                                       if (hasWest && values[northWest] == ERROR_VALUE) {
+                                               w = weight(dt.values[northWest], dtmax, SQRT_2);
+                                               graph.addDirectedEdge(k, northWest, w);
+                                       }
+                                       
+                                       if (values[north] == ERROR_VALUE) {
+                                               w = weight(dt.values[north], dtmax, 1);
+                                               graph.addDirectedEdge(k, north, w);
+                                       }
+                               
+                                       if (hasEast && values[northEast] == ERROR_VALUE) {
+                                               w = weight(dt.values[northEast], dtmax, SQRT_2);
+                                               graph.addDirectedEdge(k, northEast, w);
+                                       }
+                               }
+                               
+                               if (hasWest && values[west] == ERROR_VALUE) {
+                                       w = weight(dt.values[west], dtmax, 1);
+                                       graph.addDirectedEdge(k, west, w);
+                               }
+                               
+                               if (hasEast && values[east] == ERROR_VALUE) {
+                                       w = weight(dt.values[east], dtmax, 1);
+                                       graph.addDirectedEdge(k, east, w);
+                               }
+                               
+                               if (hasSouth) {
+                                       if (hasWest && values[southWest] == ERROR_VALUE) {
+                                               w = weight(dt.values[southWest], dtmax, SQRT_2);
+                                               graph.addDirectedEdge(k, southWest, w);
+                                       }
+                                       
+                                       if (values[south] == ERROR_VALUE) {
+                                               w = weight(dt.values[south], dtmax, 1);
+                                               graph.addDirectedEdge(k, south, w);
+                                       }
+                                       
+                                       if (hasEast && values[southEast] == ERROR_VALUE) {
+                                               w = weight(dt.values[southEast], dtmax, SQRT_2);
+                                               graph.addDirectedEdge(k, southEast, w);
+                                       }
+                               }
+                       }
+               }
+               
+               return graph;
+       }
+       
+       private static double weight(double n, double m, double d) {
+               return d*Math.exp(-n/m);
+       }
+
+       private static DoubleMatrix distanceTransform(ByteMatrix error) {
+               DistanceTransform dt = new DistanceTransform();
+               dt.init(error, Constants.ERROR_VALUE);
+               return dt.computeTransform();
+       }
+       
+       private static boolean isStoppingCriteriaSatisfied(DoubleMatrix dt) {
+               return dt.maxValue() < 2.0;
+       }
+       
+       private static boolean nonzero(DoubleMatrix matrix) {
+               for (int i = 0; i < matrix.size; i++) {
+                       if (matrix.values[i] != 0) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+       
+       public static boolean isNonDeterministic() {
+               return true;
+       }
+}
diff --git a/Annotation/src/ie/dcu/eval/AbstractEvaluator.class b/Annotation/src/ie/dcu/eval/AbstractEvaluator.class
new file mode 100644 (file)
index 0000000..91fb751
Binary files /dev/null and b/Annotation/src/ie/dcu/eval/AbstractEvaluator.class differ
diff --git a/Annotation/src/ie/dcu/eval/AbstractEvaluator.java b/Annotation/src/ie/dcu/eval/AbstractEvaluator.java
new file mode 100644 (file)
index 0000000..05ca3d7
--- /dev/null
@@ -0,0 +1,181 @@
+package ie.dcu.eval;
+
+import ie.dcu.matrix.ByteMatrix;
+
+import java.util.*;
+
+/**
+ * Abstract class to make implementing evaluators easier. Subclasses should set
+ * the values of name, description and vendor in the constructor, and add all
+ * the measures that will be computed. The subclasses implementation of the run
+ * method should call {@link #setResult(String, double)} for all the measures computed.
+ * 
+ * @author Kevin McGuinness
+ */
+public abstract class AbstractEvaluator implements Evaluator {
+       
+       /**
+        * Map will contain the results of the evaluation.
+        */
+       private final Map<String, Double> results;
+       
+       
+       /**
+        * Name of the evaluator, should be set by subclass on construction.
+        */
+       protected String name;
+       
+       
+       /**
+        * Description of the evaluator, should be set by subclass on construction.
+        */
+       protected String description;
+       
+       
+       /**
+        * Vendor of the evaluator, should be set by subclass on construction.
+        */
+       protected String vendor;
+
+       
+       /**
+        * Cached names of the measures;
+        */
+       private transient String[] measures;
+       
+
+       /**
+        * Constructor.
+        */
+       public AbstractEvaluator() {
+               // Use a tree-map as we expect only a small number of measures
+               results = new TreeMap<String, Double>();
+       }
+       
+
+       /**
+        * Default implementation returns the name field.
+        */
+       public String getName() {
+               return name;
+       }
+
+
+       /**
+        * Default implementation returns the description field.
+        */
+       public String getDescription() {
+               return description;
+       }
+
+
+       /**
+        * Default implementation returns the vendor field.
+        */
+       public String getVendor() {
+               return vendor;
+       }
+
+
+       
+       public String[] getMeasures() {
+               if (measures == null) {
+                       Set<String> keySet = results.keySet();
+                       measures = keySet.toArray(new String[keySet.size()]);
+               }
+               return measures;
+       }
+
+
+       public double getMeasure(String name) 
+               throws IllegalStateException, IllegalArgumentException {
+               
+               Double measure = results.get(name);
+               
+               if (measure == null) {
+                       
+                       if (results.containsKey(name)) {
+                               
+                               // Measure not computed by run method
+                               throw new IllegalStateException();
+                       }
+                       
+                       // Unknown measure name
+                       throw new IllegalArgumentException(name + " is not a valid measure");
+               }
+               
+               return measure;
+       }
+
+       
+       /**
+        * Add a measure that the evaluator will compute. Subclasses should add all
+        * their measures using this method in their constructor.
+        * 
+        * @param name
+        *          The name of the measure.
+        */
+       protected void addMeasure(String name) {
+               // Add measure with null value
+               results.put(name, null);
+               
+               // Invalidate cache
+               measures = null;
+       }
+       
+       
+       /**
+        * Set the value of a measure resulting from running the evaluator. This
+        * method should be called at the end of run to set the results of the
+        * evaluation.
+        * 
+        * @param name
+        *          The name of the measure.
+        * @param value
+        *          The computed value.
+        * @throws IllegalArgumentException
+        *           If the name of the measure has not been added with
+        *           {@link #addMeasure(String)}
+        */
+       protected void setResult(String name, double value) 
+               throws IllegalArgumentException {
+       
+               // Ensure we're a real measure
+               if (!results.containsKey(name)) {
+                       throw new IllegalArgumentException();
+               }
+               
+               results.put(name, value);
+       }
+       
+       
+       /**
+        * Checks if the two masks are non-null and the have the same dimensions. If
+        * they do not, an IllegalArgumentException is thrown. Method is provided to
+        * let subclasses easily validate parameters to run().
+        * 
+        * @param a
+        *          The first segmentation mask
+        * @param b
+        *          The second segmentation mask
+        * @throws IllegalArgumentException
+        *           If either mask is <code>null</code> or they have different
+        *           dimensions.
+        */
+       protected void check(ByteMatrix a, ByteMatrix b) 
+               throws IllegalArgumentException 
+       {
+               if (a == null) {
+                       throw new IllegalArgumentException("null mask");
+               }
+               
+               if (b == null) {
+                       throw new IllegalArgumentException("null mask");
+               }
+               
+               if (!a.sizeEquals(b)) {
+                       throw new IllegalArgumentException("unequal dimensions");
+               }
+               
+       }
+}
diff --git a/Annotation/src/ie/dcu/eval/BestEvaluator.class b/Annotation/src/ie/dcu/eval/BestEvaluator.class
new file mode 100644 (file)
index 0000000..6eeb15b
Binary files /dev/null and b/Annotation/src/ie/dcu/eval/BestEvaluator.class differ
diff --git a/Annotation/src/ie/dcu/eval/BestEvaluator.java b/Annotation/src/ie/dcu/eval/BestEvaluator.java
new file mode 100644 (file)
index 0000000..e8995a4
--- /dev/null
@@ -0,0 +1,84 @@
+package ie.dcu.eval;
+
+import ie.dcu.matrix.ByteMatrix;
+
+/**
+ * Extracts the most useful measures from the other two evaluators
+ * 
+ * @author Kevin McGuinness
+ */
+public class BestEvaluator extends AbstractEvaluator {
+       
+       /**
+        * Object Jaccard index.
+        */
+       public static final String OBJECT_ACCURACY = "Object";
+       
+       /**
+        * Fuzzy boundary accuracy measure.
+        */
+       public static final String BOUNDARY_ACCURACY = "Boundary";
+       
+       /**
+        * Measures computed by the confusion matrix evaluator
+        */
+       private final ConfusionMatrixEvaluator cmEvaluator;
+       
+       /**
+        * Measures computed by the boundary accuracy evaluator
+        */
+       private final BoundaryAccuracyEvaluator baEvaluator;
+
+       /**
+        * Constructor.
+        */
+       public BestEvaluator() {
+               
+               // Create evaluators
+               cmEvaluator = new ConfusionMatrixEvaluator();
+               baEvaluator = new BoundaryAccuracyEvaluator();
+               
+               // Setup evaluator
+               name = "Boundary and Object Accuracy Evaluator";
+               description = "Computes object jaccard index and fuzzy boundary index";
+               vendor = "Kevin McGuinness";
+       
+               // Add measures
+               addMeasure(OBJECT_ACCURACY);
+               addMeasure(BOUNDARY_ACCURACY);
+       }
+
+       /**
+        * Set the sigma parameter.
+        * 
+        * The sigma parameter controls the tolerance of the fuzzy Jaccard
+        * measure.
+        * 
+        * @param sigma A value greater than zero.
+        */
+       public void setSigma(double sigma) {
+               baEvaluator.setSigma(sigma);
+       }
+       
+       /**
+        * Get the sigma parameter.
+        */
+       public double getSigma() {
+               return baEvaluator.getSigma();
+       }
+       
+       /**
+        * Run the evaluator.
+        */
+       public void run(ByteMatrix mask, ByteMatrix gt)
+               throws IllegalArgumentException 
+       {
+               cmEvaluator.run(mask, gt);
+               baEvaluator.run(mask, gt);
+               
+               setResult(OBJECT_ACCURACY, cmEvaluator.getMeasure(
+                               ConfusionMatrixEvaluator.JACCARD));
+               setResult(BOUNDARY_ACCURACY, baEvaluator.getMeasure(
+                               BoundaryAccuracyEvaluator.FUZZY_ACCURACY));
+       }
+}
diff --git a/Annotation/src/ie/dcu/eval/BinaryClassifierEvaluation.class b/Annotation/src/ie/dcu/eval/BinaryClassifierEvaluation.class
new file mode 100644 (file)
index 0000000..27f9238
Binary files /dev/null and b/Annotation/src/ie/dcu/eval/BinaryClassifierEvaluation.class differ
diff --git a/Annotation/src/ie/dcu/eval/BinaryClassifierEvaluation.java b/Annotation/src/ie/dcu/eval/BinaryClassifierEvaluation.java
new file mode 100644 (file)
index 0000000..1425436
--- /dev/null
@@ -0,0 +1,216 @@
+package ie.dcu.eval;
+
+import static java.lang.Math.sqrt;
+
+
+/**
+ * Computes a variety of statistical measures and indices to evaluate binary
+ * classifiers based on a confusion matrix computed against a reference.
+ * 
+ * @author Kevin McGuinness
+ */
+public class BinaryClassifierEvaluation {
+       public final double tp;
+       public final double fp;
+       public final double tn;
+       public final double fn;
+       public final double total;
+       
+       
+       public BinaryClassifierEvaluation(int[][] c) {
+               this(c[0][0], c[0][1], c[1][0], c[1][1]);
+       }
+       
+       
+       public BinaryClassifierEvaluation(long[][] c) {
+               this(c[0][0], c[0][1], c[1][0], c[1][1]);
+       }
+       
+       
+       public BinaryClassifierEvaluation(long tp, long fn, long fp, long tn) {
+               check(this.tp = tp);
+               check(this.fp = fp);
+               check(this.tn = tn);
+               check(this.fn = fn);
+               this.total = tp + fp + tn + fn;
+       }
+       
+       
+       public final double getTotal() {
+               return total;
+       }
+
+
+       public final double getPositiveReference() {
+               return tp + fn;
+       }
+
+
+       public final double getNegativeReference() {
+               return tn + fp;
+       }
+
+
+       public final double getPositiveResponse() {
+               return tp + fp;
+       }
+
+
+       public final double getNegativeResponse() {
+               return tn + fn;
+       }
+
+       
+       public final double getCorrectResponse() {
+               return tp + tn;
+       }
+
+
+       public final double getIncorrectResponse() {
+               return fp + fn;
+       }
+       
+       
+       public final double getReferenceLikelihood() {
+               return (tp + fn) / total;
+       }
+
+
+       public final double getResponseLikelihood() {
+               return (tp + fp) / total;
+       }
+
+
+       public final double getAccuracy() {
+               return (tp + tn) / total;
+       }
+       
+
+       public final double getRecall() {
+               return tp / (tp + fn);
+       }
+
+       public final double getPrecision() {
+               return tp / (tp + fp);
+       }
+
+
+       public final double getRejectionRecall() {
+               return tn / (tn + fp);
+       }
+
+
+       public final double getRejectionPrecision() {
+               return tn / (tn + fn);
+       }
+
+
+       public final double getFMeasure() {
+               return getFMeasure(1.0);
+       }
+
+
+       public final double getFMeasure(double beta) {
+               double b = beta * beta, p = getPrecision(), r = getRecall();
+               return (1.0 + b) * p * r / (r + (b * p));
+       }
+
+       
+       public final double getRandIndex() {
+               // Same as accuracy in the binary case
+               return getAccuracy();
+       }
+       
+
+       public final double getJaccardIndex() {
+               // Jaccard similarity coefficient J
+               return tp / (tp + fn + fp);
+       }
+
+       
+       public final double getJaccardDistance() {
+               // Jaccard distance J'
+               return (fp + fn) / (fp + fn + tp);
+       }
+       
+       
+       public final double getFowlkesMallowsIndex() {
+               // Fowlkes-Mallows 83 - A method for comparing 2 hierarchical clusterings 
+               double tk = sq(tp) + sq(fn) + sq(fp) + sq(tn) - total;
+               double pk = sq(tp + fp) + sq(fn + tn) - total;
+               double qk = sq(tp + fn) + sq(fp + tn) - total;
+               return tk / sqrt(pk*qk);
+       }
+       
+
+       public final double getChiSquared() {
+               double d = tp * tn - fp * fn;
+               return total * d * d / ((tp + fn) * (fp + tn) * (tp + fp) * (fn + tn));
+       }
+
+
+       public final double getPhiSquared() {
+               return getChiSquared() / total;
+       }
+
+
+       public final double getYulesQ() {
+               return (tp * tn - fp * fn) / (tp * tn + fp * fn);
+       }
+
+
+       public final double getYulesY() {
+               return (sqrt(tp * tn) - sqrt(fp * fn)) / (sqrt(tp * tn) + sqrt(fp * fn));
+       }
+
+
+       public final double getAccuracyDeviation() {
+               double a = getAccuracy();
+               return sqrt(a * (1.0 - a) / total);
+       }
+
+
+       public final double getRandomAccuracy() {
+               double ref = (tp + fn) / total;
+               double res = (tp + fp) / total;
+               return ref * res + (1.0 - ref) * (1.0 - res);
+       }
+
+
+       public final double getRandomAccuracyUnbiased() {
+               double avg = tp / total + (fn + fp) / (2.0 * total); 
+               return avg * avg + (1.0 - avg) * (1.0 - avg);
+       }
+
+
+       public final double getKappa() {
+               return kappa(getAccuracy(), getRandomAccuracy());
+       }
+
+
+       public final double getKappaUnbiased() {
+               return kappa(getAccuracy(), getRandomAccuracyUnbiased());
+       }
+
+       
+       public final double getKappaNoPrevalence() {
+               return 2.0 * getAccuracy() - 1.0;
+       }
+
+       
+       private static double kappa(double observed, double expected) {
+               return (observed - expected) / (1 - expected);
+       }
+       
+       
+       private static double sq(double x) {
+               return x*x;
+       }
+       
+       
+       private static void check(double v) {
+               if (v < 0) {
+                       throw new IllegalArgumentException();
+               }
+       }
+}
\ No newline at end of file
diff --git a/Annotation/src/ie/dcu/eval/BoundaryAccuracyEvaluator.class b/Annotation/src/ie/dcu/eval/BoundaryAccuracyEvaluator.class
new file mode 100644 (file)
index 0000000..d5cd2f4
Binary files /dev/null and b/Annotation/src/ie/dcu/eval/BoundaryAccuracyEvaluator.class differ
diff --git a/Annotation/src/ie/dcu/eval/BoundaryAccuracyEvaluator.java b/Annotation/src/ie/dcu/eval/BoundaryAccuracyEvaluator.java
new file mode 100644 (file)
index 0000000..518b086
--- /dev/null
@@ -0,0 +1,237 @@
+package ie.dcu.eval;
+
+import ie.dcu.image.dt.DistanceTransform;
+import ie.dcu.matrix.*;
+
+/**
+ * An evaluator that computes internal object boundary accuracy using 
+ * the Jaccard and the fuzzy Jaccard indices.
+ * 
+ * @author Kevin McGuinness
+ */
+public class BoundaryAccuracyEvaluator extends AbstractEvaluator {
+       
+       /**
+        * Name of the fuzzy accuracy measure.
+        */
+       public static final String FUZZY_ACCURACY  = "FBA";
+       
+       /**
+        * Name of the binary accuracy measure.
+        */
+       public static final String BINARY_ACCURACY = "BBA";
+       
+       /**
+        * Default value of the sigma parameter.
+        */
+       public static final double DEFAULT_SIGMA = 3.5;
+       
+       /**
+        * Sigma parameter.
+        */
+       private double sigma;
+       
+       /**
+        * Constructor
+        */
+       public BoundaryAccuracyEvaluator() {
+               
+               // Setup evaluator
+               name = "Boundary Accuracy Evaluator";
+               description = "Compute internal object boundary accuracy " +
+                               "using the Jaccard and the fuzzy Jaccard measures";
+               vendor = "Kevin McGuinness";
+       
+               // Add measures
+               addMeasure(FUZZY_ACCURACY);
+               addMeasure(BINARY_ACCURACY);
+               
+               // Set default sigma value
+               sigma = DEFAULT_SIGMA;
+       }
+       
+       /**
+        * Get the sigma parameter.
+        */
+       public double getSigma() {
+               return sigma;
+       }
+
+       /**
+        * Set the sigma parameter.
+        * 
+        * The sigma parameter controls the tolerance of the fuzzy Jaccard
+        * measure.
+        * 
+        * @param sigma A value greater than zero.
+        */
+       public void setSigma(double sigma) {
+               if (sigma <= 0) {
+                       throw new IllegalArgumentException("sigma must be > 0");
+               }
+               this.sigma = sigma;
+       }
+
+       /**
+        * Run evaluator.
+        */
+       public void run(ByteMatrix a, ByteMatrix b)
+               throws IllegalArgumentException 
+       {
+               // Check arguments
+               check(a, b);
+               
+               // Find boundaries
+               ByteMatrix boundaryA = findInternalBoundary(a);
+               ByteMatrix boundaryB = findInternalBoundary(b);
+               
+               // Compute accuracy
+               double fba = fuzzyBoundaryAccuracy(boundaryA, boundaryB);
+               double bba = binaryBoundaryAccuracy(boundaryA, boundaryB);
+               
+               // Set result
+               setResult(FUZZY_ACCURACY, fba);
+               setResult(BINARY_ACCURACY, bba);
+       }
+       
+       /**
+        * Compute fuzzy boundary accuracy between given boundary masks.
+        */
+       private double fuzzyBoundaryAccuracy(
+                       ByteMatrix boundaryA, ByteMatrix boundaryB) 
+       {       
+               // Compute distance transforms
+               double[] dtA = distanceTransform(boundaryA).values;
+               double[] dtB = distanceTransform(boundaryB).values;
+               
+               // Compute Gaussian
+               applyGaussian(dtA);
+               applyGaussian(dtB);
+               
+               // Compute fuzzy Jaccard
+               return fuzzyJaccard(dtA, dtB);
+       }
+       
+       /**
+        * Compute binary boundary accuracy between given boundary masks.
+        */
+       private double binaryBoundaryAccuracy(
+                       ByteMatrix boundaryA, ByteMatrix boundaryB) 
+       {
+               // Operate directly on the masks
+               return binaryJaccard(boundaryA.values, boundaryB.values);
+       }
+       
+       /**
+        * Fuzzy jaccard computation on fuzzy masks
+        */
+       private double fuzzyJaccard(double[] a, double[] b) {
+               assert (a.length == b.length);
+
+               double num = 0;
+               double den = 0;
+
+               for (int i = 0; i < a.length; i++) {
+                       num += Math.min(a[i], b[i]);
+                       den += Math.max(a[i], b[i]);
+               }
+
+               if (den != 0.0) {
+                       num /= den;
+                       return num;
+               }
+
+               return 0.0;
+       }
+       
+       /**
+        * Binary Jaccard computation on binary masks.
+        */
+       private double binaryJaccard(byte[] a, byte[] b) {
+               assert (a.length == b.length);
+               
+               double union_v = 0;
+               double intersection = 0;
+
+               for (int i = 0; i < a.length; i++) {
+                       if (a[i] == FG || b[i] == FG) {
+                               union_v++;
+                       }
+                       if (a[i] == FG && b[i] == FG) {
+                               intersection++;
+                       }
+               }
+
+               if (union_v != 0) {
+                       return intersection / union_v;
+               }
+
+               return 0;
+       }
+       
+       /**
+        * Apply gaussian kernel to mask.
+        */
+       private void applyGaussian(double[] values) {
+               double denominator = 2.0 * sigma * sigma;
+               for (int i = 0; i < values.length; i++) {
+                       double x = values[i];
+                       values[i] = Math.exp(-(x*x) / denominator);
+               }
+       }
+       
+       /**
+        * Compute Euclidean distance transform of mask.
+        */
+       private DoubleMatrix distanceTransform(ByteMatrix m) {
+               DistanceTransform dt = new DistanceTransform();
+               dt.init(m, BG);
+               return dt.computeTransform();
+       }
+       
+       /**
+        * Determine the internal boundary of the foreground object.
+        */
+       private static ByteMatrix findInternalBoundary(ByteMatrix m) {
+       
+               ByteMatrix result = new ByteMatrix(m.rows, m.cols);
+               
+               for (int i = 0; i < m.rows; i++) {
+                       int k = i * m.cols;
+
+                       for (int j = 0; j < m.cols; j++, k++) {
+                               if (m.values[k] == FG) {
+                                       
+                                       // border pixels
+                               if (i == 0 || j == 0 || 
+                                       i == m.rows - 1 || j == m.cols - 1) 
+                               {
+                                 result.values[k] = FG;
+                                 continue;
+                               }
+                               
+                               // pixels with neighbors in background
+                               
+                               if (m.values[k-m.cols-1] == BG || // (i-1, j-1)
+                                   m.values[k-m.cols]   == BG || // (i  , j-1)
+                                   m.values[k-m.cols+1] == BG || // (i+1, j-1)
+                                   m.values[k-1]        == BG || // (i-1, j  )
+                                   m.values[k+1]        == BG || // (i+1, j  )
+                                   m.values[k+m.cols-1] == BG || // (i-1, j+1)
+                                   m.values[k+m.cols]   == BG || // (i  , j+1)
+                                   m.values[k+m.cols+1] == BG)   // (i+1, j+1)
+                               {
+                                 result.values[k] = FG;
+                               } else {
+                                 result.values[k] = BG;
+                               }
+                               } else {
+                                       result.values[k] = BG;
+                       }
+                       }
+               }
+               
+               return result;
+       }
+
+}
diff --git a/Annotation/src/ie/dcu/eval/ConfusionMatrixEvaluator.class b/Annotation/src/ie/dcu/eval/ConfusionMatrixEvaluator.class
new file mode 100644 (file)
index 0000000..5a208af
Binary files /dev/null and b/Annotation/src/ie/dcu/eval/ConfusionMatrixEvaluator.class differ
diff --git a/Annotation/src/ie/dcu/eval/ConfusionMatrixEvaluator.java b/Annotation/src/ie/dcu/eval/ConfusionMatrixEvaluator.java
new file mode 100644 (file)
index 0000000..4323679
--- /dev/null
@@ -0,0 +1,72 @@
+/**
+ * 
+ */
+package ie.dcu.eval;
+
+import ie.dcu.matrix.ByteMatrix;
+
+/**
+ * An evaluator that computes several standard statistical measure using a
+ * confusion matrix.
+ * 
+ * @author Kevin McGuinness
+ */
+public class ConfusionMatrixEvaluator extends AbstractEvaluator {
+       public static final String ACCURACY  = "Accuracy";
+       public static final String PRECISION = "Precision";
+       public static final String RECALL    = "Recall";
+       public static final String F_MEASURE = "F-Measure";
+       public static final String JACCARD   = "Jaccard";
+
+       public ConfusionMatrixEvaluator() {
+               name = "Confusion Matrix Evaluator";
+               description = "Computes standard measures using a confusion matrix";
+               vendor = "Kevin McGuinness";
+       
+               // Add measures
+               addMeasure(ACCURACY);
+               addMeasure(PRECISION);
+               addMeasure(RECALL);
+               addMeasure(F_MEASURE);
+               addMeasure(JACCARD);
+       }
+       
+       
+       public void run(ByteMatrix a, ByteMatrix b) {
+
+               // Check preconditions
+               check(a, b);            
+               
+               // Confusion matrix (confused? :-P)
+               int[][] c = new int[2][2];
+       
+               // Zero matrix
+               for (int i = 0; i < 2; i++) {
+                       for (int j = 0; j < 2; j++) {
+                               c[i][j] = 0;
+                       }
+               }
+               
+               // Compute confusion
+               for (int i = 0; i < a.size; i++) {
+                       
+                       // Indices into confusion matrix
+                       int idx1 = a.values[i] == FG ? 0 : 1;
+                       int idx2 = b.values[i] == FG ? 0 : 1;
+                       
+                       // Increment confusion
+                       c[idx1][idx2]++;
+               }
+               
+               // Compute measures and set results
+               BinaryClassifierEvaluation ev = 
+                       new BinaryClassifierEvaluation(c);
+               
+               // Set results
+               setResult(ACCURACY, ev.getAccuracy());
+               setResult(PRECISION, ev.getPrecision());
+               setResult(RECALL, ev.getRecall());
+               setResult(F_MEASURE, ev.getFMeasure());
+               setResult(JACCARD, ev.getJaccardIndex());
+       }
+}
diff --git a/Annotation/src/ie/dcu/eval/Evaluator.class b/Annotation/src/ie/dcu/eval/Evaluator.class
new file mode 100644 (file)
index 0000000..3c463c6
Binary files /dev/null and b/Annotation/src/ie/dcu/eval/Evaluator.class differ
diff --git a/Annotation/src/ie/dcu/eval/Evaluator.java b/Annotation/src/ie/dcu/eval/Evaluator.java
new file mode 100644 (file)
index 0000000..ee21e1f
--- /dev/null
@@ -0,0 +1,90 @@
+/**
+ * 
+ */
+package ie.dcu.eval;
+
+import ie.dcu.matrix.ByteMatrix;
+import ie.dcu.segment.SegmentationMask;
+
+/**
+ * Interface for a class that is capable of evaluating a segmentation mask
+ * against a ground truth.
+ * 
+ * @author Kevin McGuinness
+ */
+public interface Evaluator {
+       
+       /**
+        * Value for the foreground pixels.
+        */
+       public static final byte FG = SegmentationMask.FOREGROUND;
+       
+       /**
+        * Value for the background pixels.
+        */
+       public static final byte BG = SegmentationMask.BACKGROUND;
+       
+       /**
+        * Returns the name of the evaluator.
+        * 
+        * @return The evaluator name. (never <code>null</code>).
+        */
+       public String getName();
+
+
+       /**
+        * Returns a short description of the evaluator.
+        * 
+        * @return A description (never <code>null</code>).
+        */
+       public String getDescription();
+       
+       
+       /**
+        * Returns the name of the author or vendor.
+        * 
+        * @return The vendor.
+        */
+       public String getVendor();
+       
+       
+       /**
+        * Run the evaluator on the given mask and ground truth.
+        * 
+        * @param mask
+        *          The segmentation mask to evaluate.
+        * @param gt
+        *          The ground truth to evaluate against.
+        * @throws IllegalArgumentException
+        *           If the mask or ground truth are <code>null</code>, if they do
+        *           not have the same dimensions, or if they contain invalid pixel
+        *           values.
+        * 
+        */
+       public void run(ByteMatrix mask, ByteMatrix gt)
+               throws IllegalArgumentException;
+       
+       
+       /**
+        * Returns the names of the measures generated by this evaluator.
+        * 
+        * @return The names of the generated measures.
+        */
+       public String[] getMeasures();
+       
+       
+       /**
+        * Get the computed value of the measure with the given name.
+        * 
+        * @param name
+        *          The measure name.
+        * @return The value of the computed measure.
+        * 
+        * @throws IllegalStateException
+        *           If the run method was not previously called successfully.
+        * @throws IllegalArgumentException
+        *           If the name is not in the array returned by {@link #getMeasures()}.
+        */
+       public double getMeasure(String name) 
+               throws IllegalStateException, IllegalArgumentException;
+}
diff --git a/Annotation/src/ie/dcu/graph/dijkstra/Graph$Edge.class b/Annotation/src/ie/dcu/graph/dijkstra/Graph$Edge.class
new file mode 100644 (file)
index 0000000..4ef1f62
Binary files /dev/null and b/Annotation/src/ie/dcu/graph/dijkstra/Graph$Edge.class differ
diff --git a/Annotation/src/ie/dcu/graph/dijkstra/Graph$Node.class b/Annotation/src/ie/dcu/graph/dijkstra/Graph$Node.class
new file mode 100644 (file)
index 0000000..1f75ffa
Binary files /dev/null and b/Annotation/src/ie/dcu/graph/dijkstra/Graph$Node.class differ
diff --git a/Annotation/src/ie/dcu/graph/dijkstra/Graph.class b/Annotation/src/ie/dcu/graph/dijkstra/Graph.class
new file mode 100644 (file)
index 0000000..4729f55
Binary files /dev/null and b/Annotation/src/ie/dcu/graph/dijkstra/Graph.class differ
diff --git a/Annotation/src/ie/dcu/graph/dijkstra/Graph.java b/Annotation/src/ie/dcu/graph/dijkstra/Graph.java
new file mode 100644 (file)
index 0000000..42d4c6a
--- /dev/null
@@ -0,0 +1,377 @@
+package ie.dcu.graph.dijkstra;
+
+import java.util.*;
+
+/**
+ * Implementation of Dijkstra's shortest path algorithm.
+ * 
+ * @author Kevin McGuinness
+ * 
+ * @param <T>
+ *        The node type for the graph.
+ */
+public class Graph<T> {
+       
+       /**
+        * Map of nodes to node objects.
+        */
+       private final Map<T, Node<T>> nodes;
+       
+       /**
+        * The source node from which all paths are found.
+        */
+       private T source;
+       
+       /**
+        * Flag to indicate whether or not the algorithm has been run.
+        */
+       private boolean done;
+       
+       /**
+        * Construct empty graph.
+        */
+       public Graph() {
+               nodes = new HashMap<T, Node<T>>();
+               done = false;
+       }
+       
+       /**
+        * Construct empty graph with the given initial capacity of nodes.
+        */
+       public Graph(int initialCapacity) {
+               nodes = new HashMap<T, Node<T>>(initialCapacity);
+               done = false;
+       }
+       
+       /**
+        * Add a directed edge between the given source and target objects.
+        */
+       public void addDirectedEdge(T source, T target, double weight) {
+               checkWeight(weight);
+               
+               // Get source node
+               Node<T> srcNode = nodes.get(source);
+               if (srcNode == null) {
+                       srcNode = new Node<T>(source);
+                       nodes.put(source, srcNode);
+               }
+               
+               // Get target node
+               Node<T> dstNode = nodes.get(target);
+               if (dstNode == null) {
+                       dstNode = new Node<T>(target);
+                       nodes.put(target, dstNode);
+               }
+               
+               // Add edge
+               srcNode.addDirectedEdge(dstNode, weight);
+               done = false;
+       }
+       
+       /**
+        * Add an undirected edge between the given nodes
+        */
+       public void addUndirectedEdge(T node1, T node2, double weight) {
+               checkWeight(weight);
+               
+               // Get source node
+               Node<T> srcNode = nodes.get(node1);
+               if (srcNode == null) {
+                       srcNode = new Node<T>(node1);
+                       nodes.put(node1, srcNode);
+               }
+               
+               // Get target node
+               Node<T> dstNode = nodes.get(node2);
+               if (dstNode == null) {
+                       dstNode = new Node<T>(node2);
+                       nodes.put(node2, dstNode);
+               }
+               
+               // Add edge
+               srcNode.addDirectedEdge(dstNode, weight);
+               dstNode.addDirectedEdge(srcNode, weight);
+               done = false;
+       }
+       
+       /**
+        * Returns the (unmodifiable) set of nodes in the graph.
+        */
+       public Set<T> nodes() {
+               return Collections.unmodifiableSet(nodes.keySet());
+       }
+       
+       /**
+        * Returns true if the given object is a node in the graph.
+        */
+       public boolean hasNode(T node) {
+               return nodes.containsKey(node);
+       }
+       
+       /**
+        * Returns the edge weight for the directed edge between src and dst, or
+        * positive infinity if there is no such edge.
+        */
+       public double getEdgeWeight(T src, T dst) {
+               Node<T> n1 = nodes.get(src);
+               if (n1 != null) {
+                       for (Edge<T> edge : n1.edges) {
+                               if (edge.target.equals(dst)) {
+                                       return edge.weight;
+                               }
+                       }
+               }
+               return Double.POSITIVE_INFINITY;
+       }
+       
+       /**
+        * Run Dijkstra's method for the given source node.
+        */
+       public void findPaths(T source) {
+               
+               if (!hasNode(source)) {
+                       throw new IllegalArgumentException("src node not in graph");
+               }
+               
+               // Check if we are re-running for a new source node
+               if (this.source != source) {
+                       this.source = source;
+                       this.done = false;
+               }
+               
+               if (!done) {
+                       
+                       // Initialize nodes
+                       for (Node<T> node : nodes.values()) {
+                               node.visited = false;
+                               node.distance = Double.POSITIVE_INFINITY;
+                               node.previous = null;
+                       }
+                       
+                       // Create node queue
+                       PriorityQueue<Node<T>> queue = 
+                               new PriorityQueue<Node<T>>();
+                       
+                       // Set distance to zero and add first node to the queue
+                       Node<T> node = nodes.get(source);
+                       node.distance = 0.0;
+                       queue.add(node);
+                       
+                       // Run Dijkstra's method
+                       while (!queue.isEmpty()) {
+                               node = queue.remove();
+                               
+                               if (node.visited) {
+                                       continue;
+                               }
+                       
+                               node.visited = true;
+                               
+                               for (Edge<T> edge : node.edges) {
+                                       Node<T> target = edge.target;
+
+                                       double distance = node.distance + edge.weight;
+                                       if (distance < target.distance) {
+                                               target.previous = node;
+                                               target.distance = distance;
+                                       }
+                                       
+                                       if (!target.visited) {
+                                               queue.add(target);
+                                       }
+                               }
+                       }
+                       
+                       // Done
+                       done = true;
+               }
+       }
+       
+       /**
+        * Returns the source node or null if the {@link #findPaths(Object)}
+        * method has not yet been called.
+        */
+       public T getSource() {
+               return source;
+       }
+
+       /**
+        * Returns the shortest path from the source to the object.
+        * 
+        * @throws IllegalStateException
+        *         if the {@link #findPaths(Object)} function has not been called.
+        */
+       public List<T> getPathTo(T object) {
+               List<T> path = getPathFrom(object);
+               Collections.reverse(path);
+               return path;
+       }
+       
+       /**
+        * Returns the shortest path from the object to the source.
+        * 
+        * @throws IllegalStateException
+        *         if the {@link #findPaths(Object)} function has not been called.
+        */
+       public List<T> getPathFrom(T object) {
+               ensureDone();
+               Node<T> node = nodes.get(object);
+               List<T> list = new LinkedList<T>();
+               while (node != null) {
+                       list.add(node.object);
+                       node = node.previous;
+               }
+               return list;
+       }
+       
+       /**
+        * Get the distance to the object. Returns infinity if the object is
+        * not in the graph.
+        */
+       public double getDistanceTo(T object) {
+               ensureDone();
+               Node<T> node = nodes.get(object);
+               return node != null ? node.distance : Double.POSITIVE_INFINITY;
+       }
+       
+       /**
+        * Get the distance from the source node to the farthest node in graph. 
+        * Returns zero if there are no nodes.
+        */
+       public double getDistanceOfLongestPath() {
+               double max = 0.0;
+               for (Node<T> n : nodes.values()) {
+                       if (n.distance > max) {
+                               max = n.distance;
+                       }
+               }
+               return max;
+       }
+       
+       /**
+        * Returns the node that is farthest away from the source node.
+        * 
+        * @throws IllegalStateException
+        *         if the {@link #findPaths(Object)} function has not been called.
+        */
+       public T getFarthestNode() {
+               ensureDone();
+               
+               T node = null;
+               double max = 0.0;
+               for (Node<T> n : nodes.values()) {
+                       if (n.distance > max) {
+                               max = n.distance;
+                               node = n.object;
+                       }
+               }
+               
+               return node;
+       }
+       
+       /**
+        * Throws an exception if the done flag is not set.
+        */
+       private final void ensureDone() {
+               if (!done) {
+                       throw new IllegalStateException("findPaths never called");
+               }
+       }
+       
+       /**
+        * Check the specified edge weight is valid.
+        */
+       private static void checkWeight(double weight) {
+               if (weight < 0) {
+                       throw new IllegalArgumentException("negative weights not allowed");
+               }
+               
+               if (weight == Double.POSITIVE_INFINITY) {
+                       throw new IllegalArgumentException("infinite weights not allowed");
+               }
+       }
+       
+       /**
+        * Graph node containing an object of type T.
+        */
+       private static class Node<T> implements Comparable<Node<?>> {
+               
+               /**
+                * The object the node contains.
+                */
+               public final T object;
+               
+               /**
+                * List of edges to adjacent nodes.
+                */
+               public final List<Edge<T>> edges;
+               
+               /**
+                * Flag to indicate the node has been visited (dijkstras algorithm).
+                */
+               public boolean visited;
+               
+               /**
+                * The minimum distance so far to this node (dijkstras algorithm)
+                */
+               public double distance;
+               
+               /**
+                * The previous node in the shortest path.
+                */
+               public Node<T> previous;
+               
+               /**
+                * Construct the node for an object.
+                * 
+                * @param object An object (non-null)
+                */
+               public Node(T object) {
+                       assert (object != null);
+                       this.object = object;
+                       this.edges = new ArrayList<Edge<T>>(8);
+                       this.visited = false;
+                       this.distance = Double.POSITIVE_INFINITY;
+                       this.previous = null;
+               }
+               
+               /**
+                * Add a directed edge between this node and an adjacent one.
+                */
+               public final void addDirectedEdge(Node<T> target, double weight) {
+                       edges.add(new Edge<T>(target, weight));
+               }
+               
+               /**
+                * Nodes are sorted based on distance.
+                */
+               public int compareTo(Node<?> n) {
+                       return distance < n.distance ? -1 : (distance == n.distance ? 0 : 1);
+               }
+       }
+       
+       /**
+        * A weighted directed edge.
+        */
+       private static class Edge<T> {
+               
+               /**
+                * Target node
+                */
+               public final Node<T> target;
+               
+               /**
+                * Edge weight
+                */
+               public final double weight;
+               
+               /**
+                * Edge constructor
+                */
+               public Edge(Node<T> target, double weight) {
+                       assert (target != null);
+                       this.target = target;
+                       this.weight = weight;
+               }
+       }
+}
diff --git a/Annotation/src/ie/dcu/graph/dijkstra/IntGraph$Edge.class b/Annotation/src/ie/dcu/graph/dijkstra/IntGraph$Edge.class
new file mode 100644 (file)
index 0000000..5b2e720
Binary files /dev/null and b/Annotation/src/ie/dcu/graph/dijkstra/IntGraph$Edge.class differ
diff --git a/Annotation/src/ie/dcu/graph/dijkstra/IntGraph$Node.class b/Annotation/src/ie/dcu/graph/dijkstra/IntGraph$Node.class
new file mode 100644 (file)
index 0000000..435b7bd
Binary files /dev/null and b/Annotation/src/ie/dcu/graph/dijkstra/IntGraph$Node.class differ
diff --git a/Annotation/src/ie/dcu/graph/dijkstra/IntGraph.class b/Annotation/src/ie/dcu/graph/dijkstra/IntGraph.class
new file mode 100644 (file)
index 0000000..ed47c00
Binary files /dev/null and b/Annotation/src/ie/dcu/graph/dijkstra/IntGraph.class differ
diff --git a/Annotation/src/ie/dcu/graph/dijkstra/IntGraph.java b/Annotation/src/ie/dcu/graph/dijkstra/IntGraph.java
new file mode 100644 (file)
index 0000000..fd18174
--- /dev/null
@@ -0,0 +1,397 @@
+package ie.dcu.graph.dijkstra;
+
+import java.util.*;
+
+/**
+ * Implementation of Dijkstra's shortest path algorithm, optimized
+ * for nodes that have integer indices in a fixed integer range.
+ * 
+ * @author Kevin McGuinness
+ */
+public class IntGraph {
+       
+       /**
+        * Map of node indices to node objects.
+        */
+       private final Node[] nodes;
+       
+       /**
+        * The source node from which all paths are found.
+        */
+       private int source;
+       
+       /**
+        * Flag to indicate whether or not the algorithm has been run.
+        */
+       private boolean done;
+
+       /**
+        * Number of nodes inserted into the graph.
+        */
+       private int nodeCount;
+       
+       /**
+        * Construct empty graph which can hold nodes up to the given node index.
+        */
+       public IntGraph(int maxNodeIndex) {
+               nodes = new Node[maxNodeIndex];
+               nodeCount = 0;
+               done = false;
+       }
+       
+       /**
+        * Reset (clear) the graph.
+        */
+       public void clear() {
+               Arrays.fill(nodes, null);
+               nodeCount = 0;
+               done = false;
+       }
+       
+       /**
+        * Add a directed edge between the given source and target objects.
+        */
+       public void addDirectedEdge(int source, int target, double weight) {
+               checkWeight(weight);
+               
+               // Get source node
+               Node srcNode = nodes[source];
+               if (srcNode == null) {
+                       srcNode = nodes[source] = new Node(source);
+                       nodeCount++;
+               }
+               
+               // Get target node
+               Node dstNode = nodes[target];
+               if (dstNode == null) {
+                       dstNode = nodes[target] = new Node(target);
+                       nodeCount++;
+               }
+               
+               // Add edge
+               srcNode.addDirectedEdge(dstNode, weight);
+               done = false;
+       }
+       
+       /**
+        * Add an undirected edge between the given nodes
+        */
+       public void addUndirectedEdge(int node1, int node2, double weight) {
+               checkWeight(weight);
+               
+               // Get source node
+               Node srcNode = nodes[node1];
+               if (srcNode == null) {
+                       srcNode = nodes[node1] = new Node(node1);
+                       nodeCount++;
+               }
+               
+               // Get target node
+               Node dstNode = nodes[node2];
+               if (dstNode == null) {
+                       dstNode = nodes[node2] = new Node(node2);
+                       nodeCount++;
+               }
+               
+               // Add edge
+               srcNode.addDirectedEdge(dstNode, weight);
+               dstNode.addDirectedEdge(srcNode, weight);
+               done = false;
+       }
+       
+       /**
+        * Returns the set of nodes in the graph.
+        */
+       public Set<Integer> nodes() {
+               Set<Integer> nodeSet = new HashSet<Integer>();
+               for (int i = 0; i < nodes.length; i++) {
+                       if (nodes[i] != null) {
+                               nodeSet.add(i);
+                       }
+               }
+               return nodeSet;
+       }
+       
+       /**
+        * Returns true if the given object is a node in the graph.
+        */
+       public boolean hasNode(int node) {
+               return nodes[node] != null;
+       }
+       
+       /**
+        * Returns the edge weight for the directed edge between src and dst, or
+        * positive infinity if there is no such edge.
+        */
+       public double getEdgeWeight(int src, int dst) {
+               Node n1 = nodes[src];
+               if (n1 != null) {
+                       for (Edge edge : n1.edges) {
+                               if (edge.target.equals(dst)) {
+                                       return edge.weight;
+                               }
+                       }
+               }
+               return Double.POSITIVE_INFINITY;
+       }
+       
+       /**
+        * Run Dijkstra's method for the given source node.
+        */
+       public void findPaths(int source) {
+               
+               if (!hasNode(source)) {
+                       throw new IllegalArgumentException("src node not in graph: " + source);
+               }
+               
+               // Check if we are re-running for a new source node
+               if (this.source != source) {
+                       this.source = source;
+                       this.done = false;
+               }
+               
+               if (!done) {
+                       
+                       // Initialize nodes
+                       for (Node node : nodes) {
+                               if (node != null) {
+                                       node.visited = false;
+                                       node.distance = Double.POSITIVE_INFINITY;
+                                       node.previous = null;
+                               }
+                       }
+                       
+                       // Create node queue
+                       PriorityQueue<Node> queue = 
+                               new PriorityQueue<Node>();
+                       
+                       // Set distance to zero and add first node to the queue
+                       Node node = nodes[source];
+                       node.distance = 0.0;
+                       queue.add(node);
+                       
+                       // Run Dijkstra's method
+                       while (!queue.isEmpty()) {
+                               node = queue.remove();
+                               
+                               if (node.visited) {
+                                       continue;
+                               }
+                       
+                               node.visited = true;
+                               
+                               for (Edge edge : node.edges) {
+                                       Node target = edge.target;
+                                       
+                                       if (target.visited) {
+                                               continue;
+                                       }
+                                       
+                                       double distance = node.distance + edge.weight;
+                                       if (distance < target.distance) {
+                                               target.previous = node;
+                                               target.distance = distance;
+                                       }
+                               
+                                       queue.add(target);      
+                               }
+                       }
+                       
+                       done = true;
+               }
+       }
+       
+       /**
+        * Returns the number of nodes in the graph.
+        */
+       public int getNodeCount() {
+               return nodeCount;
+       }
+       
+       /**
+        * Returns the source node or null if the {@link #findPaths(int)}
+        * method has not yet been called.
+        */
+       public int getSource() {
+               return source;
+       }
+
+       /**
+        * Returns the shortest path from the source to the object.
+        * 
+        * @throws IllegalStateException
+        *         if the {@link #findPaths(int)} function has not been called.
+        */
+       public List<Integer> getPathTo(int object) {
+               List<Integer> path = getPathFrom(object);
+               Collections.reverse(path);
+               return path;
+       }
+       
+       /**
+        * Returns the shortest path from the object to the source.
+        * 
+        * @throws IllegalStateException
+        *         if the {@link #findPaths(int)} function has not been called.
+        */
+       public List<Integer> getPathFrom(int object) {
+               ensureDone();
+               Node node = nodes[object];
+               List<Integer> list = new LinkedList<Integer>();
+               while (node != null) {
+                       list.add(node.object);
+                       node = node.previous;
+               }
+               return list;
+       }
+       
+       /**
+        * Get the distance to the object. Returns infinity if the object is
+        * not in the graph.
+        */
+       public double getDistanceTo(int object) {
+               ensureDone();
+               Node node = nodes[object];
+               return node != null ? node.distance : Double.POSITIVE_INFINITY;
+       }
+       
+       /**
+        * Get the distance from the source node to the farthest node in graph. 
+        * Returns zero if there are no nodes.
+        */
+       public double getDistanceOfLongestPath() {
+               double max = 0.0;
+               for (Node n : nodes) {
+                       if (n != null && n.distance > max) {
+                               max = n.distance;
+                       }
+               }
+               return max;
+       }
+       
+       /**
+        * Returns the node that is farthest away from the source node.
+        * 
+        * @throws IllegalStateException
+        *         if the {@link #findPaths(int)} function has not been called.
+        */
+       public int getFarthestNode() {
+               ensureDone();
+               
+               int node = -1;
+               double max = 0.0;
+               for (Node n : nodes) {
+                       if (n != null && n.distance > max) {
+                               max = n.distance;
+                               node = n.object;
+                       }
+               }
+               
+               return node;
+       }
+       
+       /**
+        * Throws an exception if the done flag is not set.
+        */
+       private final void ensureDone() {
+               if (!done) {
+                       throw new IllegalStateException("findPaths never called");
+               }
+       }
+       
+       /**
+        * Check the specified edge weight is valid.
+        */
+       private static void checkWeight(double weight) {
+               if (weight < 0) {
+                       throw new IllegalArgumentException("negative weights not allowed");
+               }
+               
+               if (weight == Double.POSITIVE_INFINITY) {
+                       throw new IllegalArgumentException("infinite weights not allowed");
+               }
+       }
+       
+       /**
+        * Graph node containing an object of type T.
+        */
+       private static class Node implements Comparable<Node> {
+               
+               /**
+                * The object the node contains.
+                */
+               public final int object;
+               
+               /**
+                * List of edges to adjacent nodes.
+                */
+               public final List<Edge> edges;
+               
+               /**
+                * Flag to indicate the node has been visited (dijkstras algorithm).
+                */
+               public boolean visited;
+               
+               /**
+                * The minimum distance so far to this node (dijkstras algorithm)
+                */
+               public double distance;
+               
+               /**
+                * The previous node in the shortest path.
+                */
+               public Node previous;
+               
+               /**
+                * Construct the node for an object.
+                * 
+                * @param object An object (non-null)
+                */
+               public Node(int object) {
+                       this.object = object;
+                       this.edges = new ArrayList<Edge>(8);
+                       this.visited = false;
+                       this.distance = Double.POSITIVE_INFINITY;
+                       this.previous = null;
+               }
+               
+               /**
+                * Add a directed edge between this node and an adjacent one.
+                */
+               public final void addDirectedEdge(Node target, double weight) {
+                       edges.add(new Edge(target, weight));
+               }
+               
+               /**
+                * Nodes are sorted based on distance.
+                */
+               public int compareTo(Node n) {
+                       return distance < n.distance ? -1 : (distance == n.distance ? 0 : 1);
+               }
+       }
+       
+       /**
+        * A weighted directed edge.
+        */
+       private static class Edge {
+               
+               /**
+                * Target node
+                */
+               public final Node target;
+               
+               /**
+                * Edge weight
+                */
+               public final double weight;
+               
+               /**
+                * Edge constructor
+                */
+               public Edge(Node target, double weight) {
+                       assert (target != null);
+                       this.target = target;
+                       this.weight = weight;
+               }
+       }
+}
diff --git a/Annotation/src/ie/dcu/image/AbstractImageOp.class b/Annotation/src/ie/dcu/image/AbstractImageOp.class
new file mode 100644 (file)
index 0000000..9f0461b
Binary files /dev/null and b/Annotation/src/ie/dcu/image/AbstractImageOp.class differ
diff --git a/Annotation/src/ie/dcu/image/AbstractImageOp.java b/Annotation/src/ie/dcu/image/AbstractImageOp.java
new file mode 100644 (file)
index 0000000..7a91060
--- /dev/null
@@ -0,0 +1,94 @@
+package ie.dcu.image;
+
+import ie.dcu.matrix.*;
+import ie.dcu.matrix.Matrix.Type;
+
+/**
+ * Abstract implementation of an {@link ImageOp}. Subclasses should implement
+ * the {@link #processImage(MatrixProvider)} method.
+ * 
+ * 
+ * @author Kevin McGuinness
+ */
+public abstract class AbstractImageOp implements ImageOp {
+
+       private MatrixProvider inputProvider;
+       private Matrix outputMatrix;
+       
+       /**
+        * Default constructor (does nothing).
+        */
+       public AbstractImageOp() {
+       }
+       
+       /**
+        * Returns <code>true</code> if the output matrix is available.
+        */
+       public boolean isProcessingComplete() {
+               return outputMatrix != null;
+       }
+       
+       /**
+        * Returns <code>true</code> if the input {@link MatrixProvider} has been
+        * set.
+        */
+       public boolean isInputProviderSet() {
+               return inputProvider != null;
+       }
+
+       /**
+        * Set the input provider. Clears the output {@link Matrix}.
+        * 
+        * @see ImageOp#setInputProvider(MatrixProvider)
+        */
+       public void setInputProvider(MatrixProvider provider) {
+               this.inputProvider = provider;
+               this.outputMatrix = null;
+       }
+       
+       /**
+        * Returns the input {@link MatrixProvider}.
+        * 
+        * @return The input {@link MatrixProvider} or <code>null</code> if it has
+        *         not been set.
+        */
+       public MatrixProvider getInputProvider() {
+               return inputProvider;
+       }
+       
+       /**
+        * Returns the output {@link Matrix}.
+        * 
+        * @return The output {@link Matrix} or <code>null</code> if it has not been
+        *         set.
+        */
+       protected Matrix getOutputMatrix() {
+               if (!isInputProviderSet()) {
+                       throw new IllegalStateException("input provider not set");
+               }
+               
+               if (!isProcessingComplete()) {
+                       outputMatrix = processImage(getInputProvider());
+               }
+               
+               return outputMatrix;
+       }
+
+       public Matrix getMatrix(boolean alwaysCopy) {
+               return getMatrix(null, false);
+       }
+
+       public Matrix getMatrix(Type type, boolean alwaysCopy) {
+               return getOutputMatrix().getMatrix(type, alwaysCopy);
+       }
+       
+       /**
+        * Process the image and return the results.
+        * 
+        * @param imageProvider
+        *        A class that can be used to obtain the input image.
+        * @return The result of the image operation.
+        */
+       protected abstract Matrix processImage(MatrixProvider imageProvider);
+
+}
diff --git a/Annotation/src/ie/dcu/image/ContourTracer$Candidate.class b/Annotation/src/ie/dcu/image/ContourTracer$Candidate.class
new file mode 100644 (file)
index 0000000..31a9585
Binary files /dev/null and b/Annotation/src/ie/dcu/image/ContourTracer$Candidate.class differ
diff --git a/Annotation/src/ie/dcu/image/ContourTracer.class b/Annotation/src/ie/dcu/image/ContourTracer.class
new file mode 100644 (file)
index 0000000..70e41ee
Binary files /dev/null and b/Annotation/src/ie/dcu/image/ContourTracer.class differ
diff --git a/Annotation/src/ie/dcu/image/ContourTracer.java b/Annotation/src/ie/dcu/image/ContourTracer.java
new file mode 100644 (file)
index 0000000..3bc95b4
--- /dev/null
@@ -0,0 +1,197 @@
+package ie.dcu.image;
+
+import ie.dcu.matrix.*;
+
+import java.awt.Polygon;
+import java.util.*;
+
+import org.eclipse.swt.graphics.Point;
+
+/**
+ * Trace contours of objects in images.
+ * 
+ * TODO: This class uses SWT points and AWT polygons...
+ * 
+ * @author Kevin McGuinness
+ */
+public class ContourTracer {
+
+       private final IntMatrix labels;
+       private final int nobjects;
+       
+       // Inversion table
+       private static final int[] INVERT = { 4,5,6,7,0,1,2,3 };
+       
+       // Neighbor count
+       private static final int NEIGHBORS = 8;
+
+       public ContourTracer(ByteMatrix mask, byte foregroundValue) {
+               ObjectLabeler mapper = new ObjectLabeler();
+               mapper.setForegroundValue(foregroundValue);
+               nobjects = mapper.label(mask);
+               labels = mapper.getLabelMap();
+       }
+       
+       public List<Polygon> trace() {
+               List<Polygon> polygons = new ArrayList<Polygon>();
+               if (labels != null) {
+                       doTrace(polygons);
+               }
+               return polygons;
+       }
+
+       private void doTrace(List<Polygon> polygons) {
+               for (int i = 1; i <= nobjects; i++) {
+                       Polygon polygon = trace(i);
+                       if (polygon != null) {
+                               polygons.add(polygon);
+                       }
+                       //break;
+               }
+       }
+       
+       
+       private Polygon trace(int object) {
+               Point e1 = findFirstObjectPixel(object);
+               
+               if (e1 != null) {
+                       // First external border pixel is to the left
+                       e1 = new Point(e1.x-1, e1.y);
+                       
+                       List<Point> pts = new ArrayList<Point>();
+                       pts.add(e1);
+                       
+                       // Find the second pixel
+                       Candidate c = findFirstCandidate(e1, object);
+                       
+                       if (c != null) {
+                               
+                               Candidate next = new Candidate(c.pt, c.direction);
+                               
+                               do {
+                                       next = findNext(next.pt, next.direction, object);
+                                       pts.add(next.pt);
+                               } while (!next.pt.equals(e1));
+                       }
+                       
+                       return toPolygon(pts);
+               }
+               
+               return null;
+       }
+       
+       private final Candidate findNext(Point pc, int dpc, int object) {
+               Candidate next = null;
+               
+               int dcp = INVERT[dpc];
+               for (int r = 0; r < 7; r++) {
+                       int de = (dcp + r) % NEIGHBORS;
+                       int di = (dcp + r + 1) % NEIGHBORS;
+                       Point pe = neighbour(pc, de);
+                       Point pi = neighbour(pc, di);
+                       if (isBackground(pe, object) && isObject(pi, object)) {
+                               next = new Candidate(pe, de);
+                       }
+               }
+               
+               return next;
+       }
+       
+       private final Point findFirstObjectPixel(int object) {
+               for (int y = 0; y < labels.rows; y++) {
+                       for (int x = 0; x < labels.cols; x++) {
+                               int label = labels.intAt(y, x); 
+                               if (label == object) {
+                                       return new Point(x, y);
+                               }
+                       }
+               }
+               
+               return null;
+       }
+       
+       static final class Candidate {
+               final Point pt;
+               final int direction;
+               
+               Candidate(Point pt, int direction) {
+                       this.pt = new Point(pt.x, pt.y);
+                       this.direction = direction;
+               }
+       }
+       
+       private final Candidate findFirstCandidate(Point p0, int object) {
+
+               // Find the next pixel
+               for (int i = 4; i < NEIGHBORS; i++) {
+                       Point p1 = neighbour(p0, i);
+                       Point p2 = neighbour(p0, (i+1) % NEIGHBORS);
+                       if (isBackground(p1, object) && isObject(p2, object)) {
+                               return new Candidate(p1, i);
+                       }
+               }
+               return null;
+       }
+       
+       
+       private final boolean isBackground(Point pt, int object) {
+               return !labels.hasIndex(pt.y, pt.x) || labels.intAt(pt.y, pt.x) != object;
+       }
+       
+       private final boolean isObject(Point pt, int label) {
+               return labels.hasIndex(pt.y, pt.x) && labels.intAt(pt.y, pt.x) == label;
+       }
+       
+       private final Point neighbour(Point pt, int n) {
+               Point np = new Point(pt.x, pt.y);
+               switch (n) {
+               case 0:
+                       np.x++;
+                       break;
+               case 1:
+                       np.x++;
+                       np.y--;
+                       break;
+               case 2:
+                       np.y--;
+                       break;
+               case 3:
+                       np.x--;
+                       np.y--;
+                       break;
+               case 4:
+                       np.x--;
+                       break;
+               case 5:
+                       np.x--;
+                       np.y++;
+                       break;
+               case 6:
+                       np.y++;
+                       break;
+               case 7:
+                       np.x++;
+                       np.y++;
+               default:
+                       assert (false);
+               }
+               return np;
+       }
+
+       
+       private static Polygon toPolygon(List<Point> pts) {
+               Polygon poly = new Polygon();
+               poly.npoints = pts.size();
+               poly.xpoints = new int[pts.size()];
+               poly.ypoints = new int[pts.size()];
+               
+               int i = 0;
+               for (Point p : pts) {
+                       poly.xpoints[i] = p.x;
+                       poly.ypoints[i] = p.y;
+                       i++;
+               }
+               return poly;
+       }
+}
+
diff --git a/Annotation/src/ie/dcu/image/ImageOp.class b/Annotation/src/ie/dcu/image/ImageOp.class
new file mode 100644 (file)
index 0000000..ddb4435
Binary files /dev/null and b/Annotation/src/ie/dcu/image/ImageOp.class differ
diff --git a/Annotation/src/ie/dcu/image/ImageOp.java b/Annotation/src/ie/dcu/image/ImageOp.java
new file mode 100644 (file)
index 0000000..b7d830d
--- /dev/null
@@ -0,0 +1,30 @@
+package ie.dcu.image;
+
+import ie.dcu.matrix.MatrixProvider;
+
+/**
+ * Interface for classes that implement operations on images.
+ * 
+ * The following is an example of how it can be used:
+ * <pre>
+ *   ByteMatrix input = ... 
+ *   ImageOp op = createImageOp(); 
+ *   op.setInputProvider(input);
+ *   ByteMatrix matrix = (ByteMatrix) op.getMatrix(Matrix.Type.Byte, false);
+ * </pre>
+ * 
+ * The above assumes that <code>createImageOp()</code> creates and returns
+ * an instance of <code>ImageOp</code>.
+ * 
+ * @author Kevin McGuinness
+ */
+public interface ImageOp extends MatrixProvider {
+       
+       /**
+        * Set the class that will provide the input for this image operation.
+        * 
+        * @param provider
+        *        A {@link MatrixProvider} instance.
+        */
+       public void setInputProvider(MatrixProvider provider);
+}
diff --git a/Annotation/src/ie/dcu/image/ObjectLabeler.class b/Annotation/src/ie/dcu/image/ObjectLabeler.class
new file mode 100644 (file)
index 0000000..d7f1cab
Binary files /dev/null and b/Annotation/src/ie/dcu/image/ObjectLabeler.class differ
diff --git a/Annotation/src/ie/dcu/image/ObjectLabeler.java b/Annotation/src/ie/dcu/image/ObjectLabeler.java
new file mode 100644 (file)
index 0000000..cdfbad1
--- /dev/null
@@ -0,0 +1,197 @@
+package ie.dcu.image;
+
+import ie.dcu.matrix.*;
+import ie.dcu.matrix.Matrix.Type;
+
+import java.util.Stack;
+
+/**
+ * Class to perform connected component analysis on a binary object mask and
+ * create a labeled map of connected components.
+ * 
+ * Connected component analysis is performed using the 8-neighborhood rule.
+ * 
+ * 
+ * @author Kevin McGuinness
+ */
+public class ObjectLabeler implements MatrixProvider {
+       
+       /**
+        * Value of the background label in the label maps produced.
+        */
+       public static final int BACKGROUND_LABEL = 0;
+       
+       /**
+        * Offsets of the row indices for each of the 8-neighbors
+        */
+       private static final int[] Ni = { -1, -1, -1,  0,  0,  1,  1,  1 };
+       
+       /**
+        * Offsets of the column values for each of the 8-neighbors
+        */
+       private static final int[] Nj = { -1,  0,  1, -1,  1, -1,  0,  1 };
+       
+       /**
+        * The label matrix.
+        */
+       private IntMatrix labels;
+       
+       /**
+        * The number of objects found in the last labeling.
+        */
+       private int objectCount;
+       
+       /**
+        * The value used to identify foreground pixels in the object mask.
+        */
+       private byte foregroundValue;
+       
+       /**
+        * Construct an object labeler with a default foreground label value of 1.
+        */
+       public ObjectLabeler() {
+               this((byte) 1);
+       }
+       
+       /**
+        * Construct an object labeler that identifies foreground pixels using the
+        * given value.
+        * 
+        * @param foregroundValue
+        *            The value used to identify foreground pixels in the mask.
+        */
+       public ObjectLabeler(byte foregroundValue) {
+               this.objectCount = 0;
+               this.foregroundValue = foregroundValue;
+       }
+       
+       /**
+        * Get the foreground value used to identify foreground pixels in the mask.
+        */
+       public byte getForegroundValue() {
+               return foregroundValue;
+       }
+
+       /**
+        * Set the foreground value used to identify foreground pixels in the mask.
+        */
+       public void setForegroundValue(byte value) {
+               foregroundValue = value;
+       }
+       
+       /**
+        * Return the number of objects found in the last labeling.
+        */
+       public int getObjectCount() {
+               return objectCount;
+       }
+       
+       /**
+        * Returns the label map computed in the last labeling. This will be null
+        * if no labeling has been performed with this labeler.
+        */
+       public IntMatrix getLabelMap() {
+               return labels;
+       }
+
+       /**
+        * Compute the connected component labeling of the given binary mask.
+        * 
+        * @param mask
+        *            A binary matrix (non null).
+        * @return The number of objects found.
+        */
+       public int label(ByteMatrix mask) {
+               labels = new IntMatrix(mask.rows, mask.cols);
+               
+               // Fill the object with the background label
+               labels.fill(BACKGROUND_LABEL);
+               
+               // Current label
+               int label = 0;
+               
+               // Labeling loop
+               for (int i = 0, k = 0; i < mask.rows; i++) {
+                       for (int j = 0; j < mask.cols; j++, k++) {
+                       
+                               if (mask.values[k] == foregroundValue &&
+                                       labels.values[k] == BACKGROUND_LABEL) 
+                               {
+                                       label++;
+                                       
+                                       // Unlabeled foreground pixel
+                                       doLabel(mask, i, j, label);
+                               } 
+                       }
+               }
+               
+               // Set and return label count
+               return (objectCount = label);
+       }
+
+       /**
+        * Internal routine for label propagation.
+        */
+       private void doLabel(ByteMatrix mask, int i, int j, int label) {
+               
+               // Stack of indices to process
+               Stack<Index2D> stack = new Stack<Index2D>();
+               stack.add(new Index2D(i, j));
+               
+               // Processing loop
+               while (!stack.isEmpty()) {
+                       
+                       Index2D idx = stack.pop();
+                       
+                       if (labels.intAt(idx) != BACKGROUND_LABEL) {
+                               // Already labeled
+                               continue;
+                       }
+                       
+                       labels.setIntAt(idx, label);
+                       
+                       // iterate over neighbors
+                       for (int k = 0; k < Ni.length; k++) {
+                               i = idx.i + Ni[k];
+                               j = idx.j + Nj[k];
+                               
+                               // Check in range
+                               if (labels.hasIndex(i, j)) {
+                                       
+                                       int offset = labels.offsetOf(i, j);
+                                       
+                                       if (labels.values[offset] == BACKGROUND_LABEL && 
+                                               mask.values[offset] == foregroundValue) 
+                                       {
+                                               stack.push(new Index2D(i, j));
+                                       }       
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Implementation of matrix provider.
+        */
+       public Matrix getMatrix(boolean alwaysCopy) {
+               return getMatrix(null, alwaysCopy);
+       }
+
+       /**
+        * Implementation of matrix provider.
+        */
+       public Matrix getMatrix(Type type, boolean alwaysCopy) {
+               if (labels == null) {
+                       throw new IllegalStateException();
+               }
+               
+               return labels.getMatrix(type, alwaysCopy);
+       }
+
+       /**
+        * Implementation of matrix provider.
+        */
+       public Type getDefaultMatrixType() {
+               return labels.getDefaultMatrixType();
+       }
+}
diff --git a/Annotation/src/ie/dcu/image/binary/AbstractBinaryImageOp.class b/Annotation/src/ie/dcu/image/binary/AbstractBinaryImageOp.class
new file mode 100644 (file)
index 0000000..09c8d21
Binary files /dev/null and b/Annotation/src/ie/dcu/image/binary/AbstractBinaryImageOp.class differ
diff --git a/Annotation/src/ie/dcu/image/binary/AbstractBinaryImageOp.java b/Annotation/src/ie/dcu/image/binary/AbstractBinaryImageOp.java
new file mode 100644 (file)
index 0000000..3c3edc5
--- /dev/null
@@ -0,0 +1,98 @@
+package ie.dcu.image.binary;
+
+import ie.dcu.image.AbstractImageOp;
+import ie.dcu.matrix.*;
+
+/**
+ * Abstract implementation of the {@link BinaryImageOp} interface.
+ * 
+ * Subclasses should implement either the {@link #processImage(ByteMatrix)} or
+ * the {@link #processImage(MatrixProvider)} method.
+ * 
+ * @author Kevin McGuinness
+ */
+public abstract class AbstractBinaryImageOp extends AbstractImageOp 
+       implements BinaryImageOp 
+{
+       /**
+        * The value that should be interpreted by the implementor as a background
+        * pixel.
+        */
+       protected byte backgroundValue;
+       
+       /**
+        * The value that should be interpreted by the implementor as a foreground
+        * pixel.
+        */
+       protected byte foregroundValue;
+
+       /**
+        * Flag indicating that the default implementation of
+        * {@link #processImage(MatrixProvider)} should request a copy of the input
+        * {@link Matrix}.
+        */
+       private boolean requestInputCopy;
+
+       /**
+        * Default constructor. Sets the {@link #foregroundValue} and
+        * {@link #backgroundValue} values to
+        * {@link BinaryImageOp#DEFAULT_FOREGROUND_VALUE} and
+        * {@link BinaryImageOp#DEFAULT_BACKGROUND_VALUE}
+        */
+       public AbstractBinaryImageOp() {
+               backgroundValue = DEFAULT_BACKGROUND_VALUE;
+               foregroundValue = DEFAULT_FOREGROUND_VALUE;
+               requestInputCopy = true;
+       }
+
+       /**
+        * Set a flag indicating whether the default implementation of
+        * {@link #processImage(MatrixProvider)} should pass a copy of the input to
+        * matrix to {@link #processImage(ByteMatrix)}.
+        * 
+        * @param requestInputCopy
+        *        <code>true</code> to have {@link #processImage(ByteMatrix)}
+        *        request a copy of the input matrix, <code>false</code> otherwise.
+        */
+       protected void setRequestInputCopy(boolean requestInputCopy) {
+               this.requestInputCopy = requestInputCopy;
+       }
+
+       public void setBackgroundValue(byte backgroundValue) {
+               this.backgroundValue = backgroundValue;
+       }
+       
+       /**
+        * Returns the value that should be interpreted by the implementor as
+        * a background pixel.
+        */
+       public byte getBackgroundValue() {
+               return backgroundValue;
+       }
+
+       public void setForegroundValue(byte foregroundValue) {
+               this.foregroundValue = foregroundValue;
+       }
+       
+       /**
+        * Returns the value that should be interpreted by the implementor as
+        * a foreground pixel.
+        */
+       public byte getForegroundValue() {
+               return foregroundValue;
+       }
+       
+       protected final Matrix processImage(MatrixProvider inputProvider) {
+               Matrix matrix = inputProvider.getMatrix(Matrix.Type.Byte, requestInputCopy);
+               return processImage((ByteMatrix) matrix);
+       }
+       
+       /**
+        * Process the image and return the results.
+        * 
+        * @param input
+        *        The input byte matrix.
+        * @return The result of the image operation.
+        */
+       protected abstract Matrix processImage(ByteMatrix input);
+}
diff --git a/Annotation/src/ie/dcu/image/binary/BinaryImageOp.class b/Annotation/src/ie/dcu/image/binary/BinaryImageOp.class
new file mode 100644 (file)
index 0000000..edc1b05
Binary files /dev/null and b/Annotation/src/ie/dcu/image/binary/BinaryImageOp.class differ
diff --git a/Annotation/src/ie/dcu/image/binary/BinaryImageOp.java b/Annotation/src/ie/dcu/image/binary/BinaryImageOp.java
new file mode 100644 (file)
index 0000000..b7d8c37
--- /dev/null
@@ -0,0 +1,39 @@
+package ie.dcu.image.binary;
+
+import ie.dcu.image.ImageOp;
+
+/**
+ * A specialization of {@link ImageOp} for binary images.
+ * 
+ * @author Kevin McGuinness
+ */
+public interface BinaryImageOp extends ImageOp {
+       
+       /**
+        * The default byte value that the image operation should consider to
+        * foreground.
+        */
+       public static final byte DEFAULT_BACKGROUND_VALUE = 0;
+
+       /**
+        * The default byte value that the image operation should consider to
+        * background.
+        */
+       public static final byte DEFAULT_FOREGROUND_VALUE = 1;
+
+       /**
+        * Set the value that the image operation should consider to be foreground.
+        * 
+        * @param foregroundValue
+        *        A byte value.
+        */
+       public void setForegroundValue(byte foregroundValue);
+
+       /**
+        * Set the value that the image operation should consider to be background.
+        * 
+        * @param backgroundValue
+        *        A byte value.
+        */
+       public void setBackgroundValue(byte backgroundValue);
+}
diff --git a/Annotation/src/ie/dcu/image/binary/DistanceTransformOp.class b/Annotation/src/ie/dcu/image/binary/DistanceTransformOp.class
new file mode 100644 (file)
index 0000000..d45091b
Binary files /dev/null and b/Annotation/src/ie/dcu/image/binary/DistanceTransformOp.class differ
diff --git a/Annotation/src/ie/dcu/image/binary/DistanceTransformOp.java b/Annotation/src/ie/dcu/image/binary/DistanceTransformOp.java
new file mode 100644 (file)
index 0000000..b904f2d
--- /dev/null
@@ -0,0 +1,34 @@
+package ie.dcu.image.binary;
+
+import ie.dcu.image.dt.DistanceTransform;
+import ie.dcu.matrix.*;
+import ie.dcu.matrix.Matrix.Type;
+
+/**
+ * Distance transform operation. This class is a {@link BinaryImageOp} wrapper
+ * for the {@link DistanceTransform} object.
+ * 
+ * @author Kevin McGuinness
+ */
+public class DistanceTransformOp extends AbstractBinaryImageOp {
+       private boolean computeSquareTransform;
+       
+       public DistanceTransformOp() {
+               setRequestInputCopy(false);
+               computeSquareTransform = false;
+       }
+
+       @Override
+       protected Matrix processImage(ByteMatrix input) {
+               DistanceTransform transform = new DistanceTransform();
+               transform.init(input, foregroundValue);
+               if (computeSquareTransform) {
+                       return transform.computeSquareTransform();
+               } 
+               return transform.computeTransform();
+       }
+
+       public Type getDefaultMatrixType() {
+               return Matrix.Type.Double;
+       }
+}
diff --git a/Annotation/src/ie/dcu/image/binary/MedialAxisTransformOp.class b/Annotation/src/ie/dcu/image/binary/MedialAxisTransformOp.class
new file mode 100644 (file)
index 0000000..f0b07b7
Binary files /dev/null and b/Annotation/src/ie/dcu/image/binary/MedialAxisTransformOp.class differ
diff --git a/Annotation/src/ie/dcu/image/binary/MedialAxisTransformOp.java b/Annotation/src/ie/dcu/image/binary/MedialAxisTransformOp.java
new file mode 100644 (file)
index 0000000..6daed38
--- /dev/null
@@ -0,0 +1,98 @@
+package ie.dcu.image.binary;
+
+import ie.dcu.image.dt.DistanceTransform;
+import ie.dcu.matrix.*;
+import ie.dcu.matrix.Matrix.Type;
+
+/**
+ * Implementation of the Medial Axis Transform (MAT).
+ * 
+ * Computes the MAT by finding the Laplace of the square distance transform.
+ * 
+ * @author Kevin McGuinness
+ */
+public class MedialAxisTransformOp extends AbstractBinaryImageOp {
+       private boolean simpleLaplace = false;
+
+       @Override
+       protected Matrix processImage(ByteMatrix input) {
+               DistanceTransform transform = new DistanceTransform();
+               transform.init(input, foregroundValue);
+               IntMatrix dt = transform.computeSquareTransform();
+               return laplace(dt).clamp(0, Integer.MAX_VALUE);
+       }
+       
+
+       private IntMatrix laplace(IntMatrix m) {
+               return simpleLaplace ? laplace4(m) : laplace8(m);
+       }
+       
+       private IntMatrix laplace4(IntMatrix m) {
+               
+               IntMatrix result = new IntMatrix(m.rows, m.cols);
+               
+               int n0, n1, n2, n3;
+               for (int i = 0; i < m.rows; i++) {
+                       
+                       n0 = (i != 0) ? 1 : 0;
+                       n3 = (i != m.rows - 1) ? 1 : 0;
+                       
+                       for (int j = 0; j < m.cols; j++) {
+                               
+                                n1 = (j != 0) ? 1 : 0;
+                                n2 = (j != m.cols-1) ? 1 : 0;
+                                
+                                int value = (n0 + n1 + n2 + n3) * m.intAt(i, j);
+                                value -= (n0 != 0) ? m.intAt(i-1, j) : 0;
+                                value -= (n1 != 0) ? m.intAt(i, j-1) : 0;
+                                value -= (n2 != 0) ? m.intAt(i, j+1) : 0;
+                                value -= (n3 != 0) ? m.intAt(i+1, j) : 0;
+                                result.setIntAt(i, j, value);
+                       }
+               }
+               
+               return result;
+       }
+       
+       private IntMatrix laplace8(IntMatrix m) {
+               IntMatrix result = new IntMatrix(m.rows, m.cols);
+               
+               int a = m.rows - 1;
+               int b = m.cols - 1;
+               
+               int n0, n1, n2, n3, n4, n5, n6, n7;
+               for (int i = 0; i < m.rows; i++) {
+                       
+                       for (int j = 0; j < m.cols; j++) {
+                               
+                               n0 = (i != 0 && j != 0) ? 1 : 0;
+                               n1 = (i != 0) ? 1 : 0;
+                               n2 = (i != 0 && j != b) ? 1 : 0;
+                               n3 = (j != 0) ? 1 : 0;
+                               n4 = (j != b) ? 1 : 0;
+                               n5 = (i != a && j != 0) ? 1 : 0;
+                               n6 = (i != a) ? 1 : 0;
+                               n7 = (i != a && j != b) ? 1 : 0;
+                               
+                               int w = (n0 + n1 + n2 + n3 + n4 + n5 + n6 + n7);
+                               int v = w * m.intAt(i, j);
+                               
+                               v -= (n0 != 0) ? m.intAt(i-1, j-1) : 0;
+                               v -= (n1 != 0) ? m.intAt(i-1, j  ) : 0;
+                               v -= (n2 != 0) ? m.intAt(i-1, j+1) : 0;
+                               v -= (n3 != 0) ? m.intAt(i  , j-1) : 0;
+                               v -= (n4 != 0) ? m.intAt(i  , j+1) : 0;
+                               v -= (n5 != 0) ? m.intAt(i+1, j-1) : 0;
+                               v -= (n6 != 0) ? m.intAt(i+1, j  ) : 0;
+                               v -= (n7 != 0) ? m.intAt(i+1, j+1) : 0;
+                               
+                               result.setIntAt(i, j, v);
+                       }
+               }
+               return result;
+       }
+
+       public Type getDefaultMatrixType() {
+               return Matrix.Type.Int;
+       }
+}
diff --git a/Annotation/src/ie/dcu/image/binary/MorphOp$Close.class b/Annotation/src/ie/dcu/image/binary/MorphOp$Close.class
new file mode 100644 (file)
index 0000000..396ddec
Binary files /dev/null and b/Annotation/src/ie/dcu/image/binary/MorphOp$Close.class differ
diff --git a/Annotation/src/ie/dcu/image/binary/MorphOp$Dilate.class b/Annotation/src/ie/dcu/image/binary/MorphOp$Dilate.class
new file mode 100644 (file)
index 0000000..7711b68
Binary files /dev/null and b/Annotation/src/ie/dcu/image/binary/MorphOp$Dilate.class differ
diff --git a/Annotation/src/ie/dcu/image/binary/MorphOp$Edge.class b/Annotation/src/ie/dcu/image/binary/MorphOp$Edge.class
new file mode 100644 (file)
index 0000000..d8da859
Binary files /dev/null and b/Annotation/src/ie/dcu/image/binary/MorphOp$Edge.class differ
diff --git a/Annotation/src/ie/dcu/image/binary/MorphOp$Erode.class b/Annotation/src/ie/dcu/image/binary/MorphOp$Erode.class
new file mode 100644 (file)
index 0000000..8220046
Binary files /dev/null and b/Annotation/src/ie/dcu/image/binary/MorphOp$Erode.class differ
diff --git a/Annotation/src/ie/dcu/image/binary/MorphOp$Open.class b/Annotation/src/ie/dcu/image/binary/MorphOp$Open.class
new file mode 100644 (file)
index 0000000..0206fd4
Binary files /dev/null and b/Annotation/src/ie/dcu/image/binary/MorphOp$Open.class differ
diff --git a/Annotation/src/ie/dcu/image/binary/MorphOp$Smooth.class b/Annotation/src/ie/dcu/image/binary/MorphOp$Smooth.class
new file mode 100644 (file)
index 0000000..f7dc57c
Binary files /dev/null and b/Annotation/src/ie/dcu/image/binary/MorphOp$Smooth.class differ
diff --git a/Annotation/src/ie/dcu/image/binary/MorphOp.class b/Annotation/src/ie/dcu/image/binary/MorphOp.class
new file mode 100644 (file)
index 0000000..d13427d
Binary files /dev/null and b/Annotation/src/ie/dcu/image/binary/MorphOp.class differ
diff --git a/Annotation/src/ie/dcu/image/binary/MorphOp.java b/Annotation/src/ie/dcu/image/binary/MorphOp.java
new file mode 100644 (file)
index 0000000..cda8789
--- /dev/null
@@ -0,0 +1,476 @@
+package ie.dcu.image.binary;
+
+import ie.dcu.matrix.*;
+import ie.dcu.matrix.Matrix.Type;
+
+/**
+ * Base class for binary morphological operations.
+ * 
+ * Implementations of different morphological operations are given as the static
+ * inner classes.
+ * 
+ * @author Kevin McGuinness
+ */
+public abstract class MorphOp extends AbstractBinaryImageOp {
+       
+       /**
+        * The structuring element for the morph.
+        */
+       protected ByteMatrix structuringElement;
+       
+       /**
+        * Get the structuring element.
+        * 
+        * @return the structuring element (may be null).
+        */
+       public ByteMatrix getStructuringElement() {
+               return structuringElement;
+       }
+
+       /**
+        * Set the structuring element. 
+        * 
+        * @param se
+        *            A structuring element (can be null).
+        */
+       public void setStructuringElement(ByteMatrix se) {
+               this.structuringElement = se;
+       }
+       
+       /**
+        * Perform a basic morph-op on the given matrix.
+        * 
+        * The operation will be either an erode or dilate depending 
+        * on the values of the a and b parameters.
+        * 
+        * @param matrix
+        *        The matrix to operate on (will be modified).
+        * @param a 
+        *        Either the foregroundValue or the backgroundValue
+        * @param b
+        *        Either the foregroundValue or the backgroundValue
+        * @return
+        *        The modified input matrix.
+        */
+       protected static ByteMatrix morph(
+                       final ByteMatrix matrix,
+                       final byte a, 
+                       final byte b
+       ) {
+               
+               final byte[] im = matrix.values;
+               
+               // Right pixel
+               for (int i = 0; i < matrix.rows; i++) {
+                       final int off = i * matrix.cols;
+                       
+                       for (int j = 0; j < matrix.cols - 1; j++) {
+                               final int idx = off + j;
+                               
+                               if (im[idx] == b && im[idx+1] == a) {
+                                       im[idx] = a;
+                               }
+                       }
+               }
+               
+               // Left pixel
+               for (int i = 0; i < matrix.rows; i++) {
+                       final int off = i * matrix.cols;
+                       
+                       for (int j = matrix.cols - 1; j > 0; j--) {
+                               final int idx = off + j;
+                               
+                               if (im[idx] == b && im[idx-1] == a) {
+                                       im[idx] = a;
+                               }
+                       }
+               }
+               
+               // Below pixel
+               for (int i = 0; i < matrix.rows - 1; i++) {
+                       final int off = i * matrix.cols;
+                       
+                       for (int j = 0; j < matrix.cols; j++) {
+                               final int idx = off + j;
+                               
+                               if (im[idx] == b && im[idx + matrix.cols] == a) {
+                                       im[idx] = a;
+                               }
+                       }
+               }
+               
+               // Above pixel
+               for (int i = matrix.rows - 1; i > 0; i--) {
+                       final int off = i * matrix.cols;
+                       
+                       for (int j = 0; j < matrix.cols; j++) {
+                               final int idx = off + j;
+                               
+                               if (im[idx] == b && im[idx - matrix.cols] == a) {
+                                       im[idx] = a;
+                               }
+                       }
+               }
+               
+               return matrix;
+       }
+
+       /**
+        * Perform a binary morphological operation with a structuring element.
+        * 
+        * @param matrix
+        *            The input matrix to morph (not modified).
+        * @param se
+        *            The structuring element.
+        * @param a
+        *            Either the foreground or background value.
+        * @param b
+        *            Either the foreground or background value.
+        * @return A matrix containing the result of the morph.
+        */
+       protected static ByteMatrix morph(
+                       final ByteMatrix matrix, 
+                       final ByteMatrix se, 
+                       final byte a, 
+                       final byte b) 
+       {       
+               final ByteMatrix result = 
+                       new ByteMatrix(matrix.rows, matrix.cols);
+               result.fill(a);
+               
+               for (int i = 0, k = 0; i < matrix.rows; i++) {
+                       for (int j = 0; j < matrix.cols; j++, k++) {
+                               
+                               if (matrix.values[k] == b) {
+                                       byte value = b;
+                                       
+                                       int im_i0 = i - (se.rows >> 1);
+                                       int im_j0 = j - (se.cols >> 1);
+                                       int se_i0 = im_i0 < 0 ? -im_i0 : 0;
+                                       int se_j0 = im_j0 < 0 ? -im_j0 : 0;
+                                       
+                                       if (im_i0 < 0) {
+                                               im_i0 = 0;
+                                       }
+                                       
+                                       if (im_j0 < 0) {
+                                               im_j0 = 0;
+                                       }
+                                       
+                                       // Iterate over structuring element
+                                       outer:
+                                       for (int se_i = se_i0, im_i = im_i0; 
+                                            se_i < se.rows && im_i < matrix.rows; 
+                                            se_i++, im_i++) 
+                                       {       
+                                               int off1 = se_i * se.cols;
+                                               int off2 = im_i * matrix.cols;
+                                               
+                                               for (int se_j = se_j0, im_j = im_j0; 
+                                                    se_j < se.cols && im_j < matrix.cols; 
+                                                    se_j++, im_j++) 
+                                               {       
+                                                       if (se.values[off1 + se_j] != 0 && 
+                                                               matrix.values[off2 + im_j] == a) 
+                                                       {
+                                                               value = a;
+                                                               break outer;    
+                                                       }
+                                               }
+                                       }
+                                       
+                                       // Set value
+                                       result.values[k] = value;
+                               } 
+                       }
+               }
+               
+               return result;
+       }
+
+       /**
+        * Applies the morphological dilate operator.
+        * 
+        * @param matrix
+        *          The matrix to operate on (will be modified).
+        * @return the input matrix
+        */
+       protected ByteMatrix dilate(ByteMatrix matrix) {
+               return morph(matrix, foregroundValue, backgroundValue);
+       }
+       
+       /**
+        * Perform a morphological dilation using the given structuring element
+        * 
+        * @param matrix
+        *          The matrix to operate on (will not be modified).
+        * @param se
+        *          The structuring element
+        * @return A matrix containing the result of the morph.
+        */
+       protected ByteMatrix dilate(ByteMatrix matrix, ByteMatrix se) {
+               if (se == null) {
+                       return dilate(matrix.clone());
+               }
+               
+               return morph(matrix, se, foregroundValue, backgroundValue);
+       }
+
+       
+       /**
+        * Applies the morphological erode operator.
+        * 
+        * @param matrix
+        *          The matrix to operate on (will be modified).
+        * @return the input matrix
+        */
+       protected ByteMatrix erode(ByteMatrix matrix) {
+               return morph(matrix, backgroundValue, foregroundValue);
+       }
+       
+       /**
+        * Perform a morphological erosion using the given structuring element
+        * 
+        * @param matrix
+        *          The matrix to operate on (will not be modified).
+        * @param se
+        *          The structuring element
+        * @return A matrix containing the result of the morph.
+        */
+       protected ByteMatrix erode(ByteMatrix matrix, ByteMatrix se) {
+               if (se == null) {
+                       return erode(matrix.clone());
+               }
+               
+               return morph(matrix, se, backgroundValue, foregroundValue);
+       }
+       
+       
+       /**
+        * Applies the morphological open operator.
+        * 
+        * @param matrix
+        *          The matrix to operate on (will be modified).
+        * @return the input matrix
+        */
+       protected ByteMatrix open(ByteMatrix matrix) {
+               return dilate(erode(matrix));
+       }
+       
+       /**
+        * Perform a morphological open using the given structuring element
+        * 
+        * @param matrix
+        *          The matrix to operate on (will not be modified).
+        * @param se
+        *          The structuring element
+        * @return A matrix containing the result of the morph.
+        */
+       protected ByteMatrix open(ByteMatrix matrix, ByteMatrix se) {
+               if (se == null) {
+                       return open(matrix.clone());
+               }
+               return dilate(erode(matrix, se), se);
+       }
+       
+       /**
+        * Applies the morphological open operator.
+        * 
+        * @param matrix
+        *          The matrix to operate on (will be modified).
+        * @return the input matrix
+        */
+       protected ByteMatrix close(ByteMatrix matrix) {
+               return erode(dilate(matrix));
+       }
+       
+       /**
+        * Perform a morphological close using the given structuring element
+        * 
+        * @param matrix
+        *          The matrix to operate on (will not be modified).
+        * @param se
+        *          The structuring element
+        * @return A matrix containing the result of the morph.
+        */
+       protected ByteMatrix close(ByteMatrix matrix, ByteMatrix se) {
+               if (se == null) {
+                       return close(matrix.clone());
+               }
+               return erode(dilate(matrix, se), se);
+       }
+       
+       /**
+        * Applies the morphological smooth operator.
+        * 
+        * @param matrix
+        *          The matrix to operate on (will be modified).
+        * @return the input matrix
+        */
+       protected ByteMatrix smooth(ByteMatrix matrix) {
+               return close(open(matrix));
+       }
+       
+       /**
+        * Perform a morphological smooth using the given structuring element
+        * 
+        * @param matrix
+        *          The matrix to operate on (will not be modified).
+        * @param se
+        *          The structuring element
+        * @return A matrix containing the result of the morph.
+        */
+       protected ByteMatrix smooth(ByteMatrix matrix, ByteMatrix se) {
+               if (se == null) {
+                       return smooth(matrix.clone());
+               }
+               return close(open(matrix, se), se);
+       }
+       
+       /**
+        * Applies the morphological edge operator.
+        * 
+        * @param matrix
+        *          The matrix to operate on (will be modified).
+        * @return the input matrix
+        */
+       protected ByteMatrix edge(ByteMatrix matrix) {
+               
+               // Dilate
+               dilate(matrix);
+               
+               // Erode to temporary
+               ByteMatrix erosion = erode(matrix.clone());
+               
+               // Remove eroded mask
+               for (int i = 0; i < matrix.size; i++) {
+                       if (erosion.values[i] == foregroundValue) {
+                               matrix.values[i] = backgroundValue;
+                       }
+               }
+               
+               return matrix;
+       }
+       
+       /**
+        * Perform a morphological edge using the given structuring element
+        * 
+        * @param matrix
+        *          The matrix to operate on (will not be modified).
+        * @param se
+        *          The structuring element
+        * @return A matrix containing the result of the morph.
+        */
+       protected ByteMatrix edge(ByteMatrix matrix, ByteMatrix se) {
+               if (se == null) {
+                       return edge(matrix.clone());
+               }
+               
+               // Dilate
+               dilate(matrix, se);
+               
+               // Erode to temporary
+               ByteMatrix erosion = erode(matrix.clone(), se);
+               
+               // Remove eroded mask
+               for (int i = 0; i < matrix.size; i++) {
+                       if (erosion.values[i] == foregroundValue) {
+                               matrix.values[i] = backgroundValue;
+                       }
+               }
+               
+               return matrix;
+       }
+       
+       /*
+        * (non-Javadoc)
+        * @see ie.dcu.cdvp.matrix.MatrixProvider#getDefaultMatrixType()
+        */
+       public Type getDefaultMatrixType() {
+               return Matrix.Type.Byte;
+       }
+       
+       /**
+        * Binary morphological erosion operation.
+        */
+       public static class Erode extends MorphOp {
+
+               @Override
+               protected ByteMatrix processImage(ByteMatrix input) {
+                       if (structuringElement == null) {
+                               return erode(input);
+                       } 
+                       return erode(input, structuringElement);
+               }
+       }
+       
+       /**
+        * Binary morphological dilation operation.
+        */
+       public static class Dilate extends MorphOp {
+
+               @Override
+               protected ByteMatrix processImage(ByteMatrix input) {
+                       if (structuringElement == null) {
+                               return dilate(input);
+                       } 
+                       return dilate(input, structuringElement);
+               }
+       }
+       
+       /**
+        * Binary morphological open operation.
+        */
+       public static class Open extends MorphOp {
+
+               @Override
+               protected ByteMatrix processImage(ByteMatrix input) {
+                       if (structuringElement == null) {
+                               return open(input);
+                       } 
+                       return open(input, structuringElement);
+               }
+       }
+       
+       /**
+        * Binary morphological close operation.
+        */
+       public static class Close extends MorphOp {
+
+               @Override
+               protected ByteMatrix processImage(ByteMatrix input) {
+                       if (structuringElement == null) {
+                               return close(input);
+                       } 
+                       return close(input, structuringElement);
+               }
+       }
+       
+       /**
+        * Binary morphological smooth operation.
+        */
+       public static class Smooth extends MorphOp {
+
+               @Override
+               protected ByteMatrix processImage(ByteMatrix input) {
+                       if (structuringElement == null) {
+                               return smooth(input);
+                       } 
+                       return smooth(input, structuringElement);
+               }
+       }
+       
+       /**
+        * Binary morphological edge operation.
+        */
+       public static class Edge extends MorphOp {
+
+               @Override
+               protected ByteMatrix processImage(ByteMatrix input) {
+                       if (structuringElement == null) {
+                               return edge(input);
+                       } 
+                       return edge(input, structuringElement);
+               }
+       }
+}
diff --git a/Annotation/src/ie/dcu/image/colormap/ColorMap.class b/Annotation/src/ie/dcu/image/colormap/ColorMap.class
new file mode 100644 (file)
index 0000000..3e1feff
Binary files /dev/null and b/Annotation/src/ie/dcu/image/colormap/ColorMap.class differ
diff --git a/Annotation/src/ie/dcu/image/colormap/ColorMap.java b/Annotation/src/ie/dcu/image/colormap/ColorMap.java
new file mode 100644 (file)
index 0000000..39b45aa
--- /dev/null
@@ -0,0 +1,83 @@
+package ie.dcu.image.colormap;
+
+import java.io.Serializable;
+
+import org.eclipse.swt.graphics.*;
+
+/**
+ * Base class for color maps.
+ * 
+ * @author Kevin McGuinness
+ */
+public class ColorMap implements Serializable {
+
+       /**
+        * Serialization UID 
+        */
+       private static final long serialVersionUID = 3514876556837016224L;
+
+       /**
+        * Color look up table. N x 3 components representing the
+        * RGB values.
+        */
+       protected final float[][] lut;
+
+       /**
+        * Create a color map of the given size.
+        */
+       protected ColorMap(int size) {
+               this.lut = new float[size][3];
+       }
+       
+       /**
+        * Create a color map from the given look up table.
+        */
+       public ColorMap(float[][] lut) {
+               if (lut == null) {
+                       throw new NullPointerException("lut == null");
+               }
+               
+               for (int i = 0; i < lut.length; i++) {
+                       if (lut[i].length != 3) {
+                               throw new IllegalArgumentException();
+                       }
+               }
+               
+               this.lut = lut;
+       }
+       
+       public int size() {
+               return lut.length;
+       }
+       
+       public final float red(int index) {
+               return lut[index][0];
+       }
+       
+       public final float green(int index) {
+               return lut[index][1];
+       }
+       
+       public final float blue(int index) {
+               return lut[index][2];
+       }
+       
+       public final RGB rgb(int index) {
+               int r = (int) (lut[index][0] * 255);
+               int g = (int) (lut[index][1] * 255);
+               int b = (int) (lut[index][2] * 255);
+               return new RGB(r, g, b);
+       }
+       
+       public PaletteData createPaletteData() {
+               RGB[] palette = new RGB[lut.length];
+               for (int i = 0; i < lut.length; i++) {
+                       int r = (int) (lut[i][0] * 255);
+                       int g = (int) (lut[i][1] * 255);
+                       int b = (int) (lut[i][2] * 255);
+                       palette[i] = new RGB(r, g, b);
+               }
+               return new PaletteData(palette);
+       }
+       
+}
diff --git a/Annotation/src/ie/dcu/image/colormap/ColorMaps$SpecCache.class b/Annotation/src/ie/dcu/image/colormap/ColorMaps$SpecCache.class
new file mode 100644 (file)
index 0000000..6fe78ea
Binary files /dev/null and b/Annotation/src/ie/dcu/image/colormap/ColorMaps$SpecCache.class differ
diff --git a/Annotation/src/ie/dcu/image/colormap/ColorMaps.class b/Annotation/src/ie/dcu/image/colormap/ColorMaps.class
new file mode 100644 (file)
index 0000000..d80bc26
Binary files /dev/null and b/Annotation/src/ie/dcu/image/colormap/ColorMaps.class differ
diff --git a/Annotation/src/ie/dcu/image/colormap/ColorMaps.java b/Annotation/src/ie/dcu/image/colormap/ColorMaps.java
new file mode 100644 (file)
index 0000000..9bcb818
--- /dev/null
@@ -0,0 +1,969 @@
+package ie.dcu.image.colormap;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A set of predefined color maps.
+ * 
+ * @author Kevin McGuinness
+ */
+public final class ColorMaps {
+       
+       /**
+        * Specification for the "binary" color map.
+        */
+       private static final float[][][] SPEC_BINARY = {
+       { // R
+         { 0.000000f, 1.000000f, 1.000000f }, 
+         { 1.000000f, 0.000000f, 0.000000f } }, 
+       { // G
+         { 0.000000f, 1.000000f, 1.000000f }, 
+         { 1.000000f, 0.000000f, 0.000000f } }, 
+       { // B
+         { 0.000000f, 1.000000f, 1.000000f }, 
+         { 1.000000f, 0.000000f, 0.000000f } } 
+       };
+       
+       /**
+        * Specification for the "grey" color map.
+        */
+       private static final float[][][] SPEC_GREY = {
+       { // R
+         { 0.000000f, 0.000000f, 0.000000f }, 
+         { 1.000000f, 1.000000f, 1.000000f } }, 
+       { // G
+         { 0.000000f, 0.000000f, 0.000000f }, 
+         { 1.000000f, 1.000000f, 1.000000f } }, 
+       { // B
+         { 0.000000f, 0.000000f, 0.000000f }, 
+         { 1.000000f, 1.000000f, 1.000000f } } 
+       };
+
+       /**
+        * Specification for the "autumn" color map.
+        */
+       private static final float[][][] SPEC_AUTUMN = {
+       { // R
+         { 0.000000f, 1.000000f, 1.000000f }, 
+         { 1.000000f, 1.000000f, 1.000000f } }, 
+       { // G
+         { 0.000000f, 0.000000f, 0.000000f }, 
+         { 1.000000f, 1.000000f, 1.000000f } }, 
+       { // B
+         { 0.000000f, 0.000000f, 0.000000f }, 
+         { 1.000000f, 0.000000f, 0.000000f } } 
+       };
+
+       /**
+        * Specification for the "bone" color map.
+        */
+       private static final float[][][] SPEC_BONE = {
+       { // R
+         { 0.000000f, 0.000000f, 0.000000f }, 
+         { 0.746032f, 0.652778f, 0.652778f }, 
+         { 1.000000f, 1.000000f, 1.000000f } }, 
+       { // G
+         { 0.000000f, 0.000000f, 0.000000f }, 
+         { 0.365079f, 0.319444f, 0.319444f }, 
+         { 0.746032f, 0.777778f, 0.777778f }, 
+         { 1.000000f, 1.000000f, 1.000000f } }, 
+       { // B
+         { 0.000000f, 0.000000f, 0.000000f }, 
+         { 0.365079f, 0.444444f, 0.444444f }, 
+         { 1.000000f, 1.000000f, 1.000000f } } 
+       };
+
+       /**
+        * Specification for the "cool" color map.
+        */
+       private static final float[][][] SPEC_COOL = {
+       { // R
+         { 0.000000f, 0.000000f, 0.000000f }, 
+         { 1.000000f, 1.000000f, 1.000000f } }, 
+       { // G
+         { 0.000000f, 1.000000f, 1.000000f }, 
+         { 1.000000f, 0.000000f, 0.000000f } }, 
+       { // B
+         { 0.000000f, 1.000000f, 1.000000f }, 
+         { 1.000000f, 1.000000f, 1.000000f } } 
+       };
+
+       /**
+        * Specification for the "copper" color map.
+        */
+       private static final float[][][] SPEC_COPPER = {
+       { // R
+         { 0.000000f, 0.000000f, 0.000000f }, 
+         { 0.809524f, 1.000000f, 1.000000f }, 
+         { 1.000000f, 1.000000f, 1.000000f } }, 
+       { // G
+         { 0.000000f, 0.000000f, 0.000000f }, 
+         { 1.000000f, 0.781200f, 0.781200f } }, 
+       { // B
+         { 0.000000f, 0.000000f, 0.000000f }, 
+         { 1.000000f, 0.497500f, 0.497500f } } 
+       };
+
+       /**
+        * Specification for the "flag" color map.
+        */
+       private static final float[][][] SPEC_FLAG = {
+       { // R
+         { 0.000000f, 1.000000f, 1.000000f }, 
+         { 0.015873f, 1.000000f, 1.000000f }, 
+         { 0.031746f, 0.000000f, 0.000000f }, 
+         { 0.047619f, 0.000000f, 0.000000f }, 
+         { 0.063492f, 1.000000f, 1.000000f }, 
+         { 0.079365f, 1.000000f, 1.000000f }, 
+         { 0.095238f, 0.000000f, 0.000000f }, 
+         { 0.111111f, 0.000000f, 0.000000f }, 
+         { 0.126984f, 1.000000f, 1.000000f }, 
+         { 0.142857f, 1.000000f, 1.000000f }, 
+         { 0.158730f, 0.000000f, 0.000000f }, 
+         { 0.174603f, 0.000000f, 0.000000f }, 
+         { 0.190476f, 1.000000f, 1.000000f }, 
+         { 0.206349f, 1.000000f, 1.000000f }, 
+         { 0.222222f, 0.000000f, 0.000000f }, 
+         { 0.238095f, 0.000000f, 0.000000f }, 
+         { 0.253968f, 1.000000f, 1.000000f }, 
+         { 0.269841f, 1.000000f, 1.000000f }, 
+         { 0.285714f, 0.000000f, 0.000000f }, 
+         { 0.301587f, 0.000000f, 0.000000f }, 
+         { 0.317460f, 1.000000f, 1.000000f }, 
+         { 0.333333f, 1.000000f, 1.000000f }, 
+         { 0.349206f, 0.000000f, 0.000000f }, 
+         { 0.365079f, 0.000000f, 0.000000f }, 
+         { 0.380952f, 1.000000f, 1.000000f }, 
+         { 0.396825f, 1.000000f, 1.000000f }, 
+         { 0.412698f, 0.000000f, 0.000000f }, 
+         { 0.428571f, 0.000000f, 0.000000f }, 
+         { 0.444444f, 1.000000f, 1.000000f }, 
+         { 0.460317f, 1.000000f, 1.000000f }, 
+         { 0.476190f, 0.000000f, 0.000000f }, 
+         { 0.492063f, 0.000000f, 0.000000f }, 
+         { 0.507937f, 1.000000f, 1.000000f }, 
+         { 0.523810f, 1.000000f, 1.000000f }, 
+         { 0.539683f, 0.000000f, 0.000000f }, 
+         { 0.555556f, 0.000000f, 0.000000f }, 
+         { 0.571429f, 1.000000f, 1.000000f }, 
+         { 0.587302f, 1.000000f, 1.000000f }, 
+         { 0.603175f, 0.000000f, 0.000000f }, 
+         { 0.619048f, 0.000000f, 0.000000f }, 
+         { 0.634921f, 1.000000f, 1.000000f }, 
+         { 0.650794f, 1.000000f, 1.000000f }, 
+         { 0.666667f, 0.000000f, 0.000000f }, 
+         { 0.682540f, 0.000000f, 0.000000f }, 
+         { 0.698413f, 1.000000f, 1.000000f }, 
+         { 0.714286f, 1.000000f, 1.000000f }, 
+         { 0.730159f, 0.000000f, 0.000000f }, 
+         { 0.746032f, 0.000000f, 0.000000f }, 
+         { 0.761905f, 1.000000f, 1.000000f }, 
+         { 0.777778f, 1.000000f, 1.000000f }, 
+         { 0.793651f, 0.000000f, 0.000000f }, 
+         { 0.809524f, 0.000000f, 0.000000f }, 
+         { 0.825397f, 1.000000f, 1.000000f }, 
+         { 0.841270f, 1.000000f, 1.000000f }, 
+         { 0.857143f, 0.000000f, 0.000000f }, 
+         { 0.873016f, 0.000000f, 0.000000f }, 
+         { 0.888889f, 1.000000f, 1.000000f }, 
+         { 0.904762f, 1.000000f, 1.000000f }, 
+         { 0.920635f, 0.000000f, 0.000000f }, 
+         { 0.936508f, 0.000000f, 0.000000f }, 
+         { 0.952381f, 1.000000f, 1.000000f }, 
+         { 0.968254f, 1.000000f, 1.000000f }, 
+         { 0.984127f, 0.000000f, 0.000000f }, 
+         { 1.000000f, 0.000000f, 0.000000f } }, 
+       { // G
+         { 0.000000f, 0.000000f, 0.000000f }, 
+         { 0.015873f, 1.000000f, 1.000000f }, 
+         { 0.031746f, 0.000000f, 0.000000f }, 
+         { 0.063492f, 0.000000f, 0.000000f }, 
+         { 0.079365f, 1.000000f, 1.000000f }, 
+         { 0.095238f, 0.000000f, 0.000000f }, 
+         { 0.126984f, 0.000000f, 0.000000f }, 
+         { 0.142857f, 1.000000f, 1.000000f }, 
+         { 0.158730f, 0.000000f, 0.000000f }, 
+         { 0.190476f, 0.000000f, 0.000000f }, 
+         { 0.206349f, 1.000000f, 1.000000f }, 
+         { 0.222222f, 0.000000f, 0.000000f }, 
+         { 0.253968f, 0.000000f, 0.000000f }, 
+         { 0.269841f, 1.000000f, 1.000000f }, 
+         { 0.285714f, 0.000000f, 0.000000f }, 
+         { 0.317460f, 0.000000f, 0.000000f }, 
+         { 0.333333f, 1.000000f, 1.000000f }, 
+         { 0.349206f, 0.000000f, 0.000000f }, 
+         { 0.380952f, 0.000000f, 0.000000f }, 
+         { 0.396825f, 1.000000f, 1.000000f }, 
+         { 0.412698f, 0.000000f, 0.000000f }, 
+         { 0.444444f, 0.000000f, 0.000000f }, 
+         { 0.460317f, 1.000000f, 1.000000f }, 
+         { 0.476190f, 0.000000f, 0.000000f }, 
+         { 0.507937f, 0.000000f, 0.000000f }, 
+         { 0.523810f, 1.000000f, 1.000000f }, 
+         { 0.539683f, 0.000000f, 0.000000f }, 
+         { 0.571429f, 0.000000f, 0.000000f }, 
+         { 0.587302f, 1.000000f, 1.000000f }, 
+         { 0.603175f, 0.000000f, 0.000000f }, 
+         { 0.634921f, 0.000000f, 0.000000f }, 
+         { 0.650794f, 1.000000f, 1.000000f }, 
+         { 0.666667f, 0.000000f, 0.000000f }, 
+         { 0.698413f, 0.000000f, 0.000000f }, 
+         { 0.714286f, 1.000000f, 1.000000f }, 
+         { 0.730159f, 0.000000f, 0.000000f }, 
+         { 0.761905f, 0.000000f, 0.000000f }, 
+         { 0.777778f, 1.000000f, 1.000000f }, 
+         { 0.793651f, 0.000000f, 0.000000f }, 
+         { 0.825397f, 0.000000f, 0.000000f }, 
+         { 0.841270f, 1.000000f, 1.000000f }, 
+         { 0.857143f, 0.000000f, 0.000000f }, 
+         { 0.888889f, 0.000000f, 0.000000f }, 
+         { 0.904762f, 1.000000f, 1.000000f }, 
+         { 0.920635f, 0.000000f, 0.000000f }, 
+         { 0.952381f, 0.000000f, 0.000000f }, 
+         { 0.968254f, 1.000000f, 1.000000f }, 
+         { 0.984127f, 0.000000f, 0.000000f }, 
+         { 1.000000f, 0.000000f, 0.000000f } }, 
+       { // B
+         { 0.000000f, 0.000000f, 0.000000f }, 
+         { 0.015873f, 1.000000f, 1.000000f }, 
+         { 0.031746f, 1.000000f, 1.000000f }, 
+         { 0.047619f, 0.000000f, 0.000000f }, 
+         { 0.063492f, 0.000000f, 0.000000f }, 
+         { 0.079365f, 1.000000f, 1.000000f }, 
+         { 0.095238f, 1.000000f, 1.000000f }, 
+         { 0.111111f, 0.000000f, 0.000000f }, 
+         { 0.126984f, 0.000000f, 0.000000f }, 
+         { 0.142857f, 1.000000f, 1.000000f }, 
+         { 0.158730f, 1.000000f, 1.000000f }, 
+         { 0.174603f, 0.000000f, 0.000000f }, 
+         { 0.190476f, 0.000000f, 0.000000f }, 
+         { 0.206349f, 1.000000f, 1.000000f }, 
+         { 0.222222f, 1.000000f, 1.000000f }, 
+         { 0.238095f, 0.000000f, 0.000000f }, 
+         { 0.253968f, 0.000000f, 0.000000f }, 
+         { 0.269841f, 1.000000f, 1.000000f }, 
+         { 0.285714f, 1.000000f, 1.000000f }, 
+         { 0.301587f, 0.000000f, 0.000000f }, 
+         { 0.317460f, 0.000000f, 0.000000f }, 
+         { 0.333333f, 1.000000f, 1.000000f }, 
+         { 0.349206f, 1.000000f, 1.000000f }, 
+         { 0.365079f, 0.000000f, 0.000000f }, 
+         { 0.380952f, 0.000000f, 0.000000f }, 
+         { 0.396825f, 1.000000f, 1.000000f }, 
+         { 0.412698f, 1.000000f, 1.000000f }, 
+         { 0.428571f, 0.000000f, 0.000000f }, 
+         { 0.444444f, 0.000000f, 0.000000f }, 
+         { 0.460317f, 1.000000f, 1.000000f }, 
+         { 0.476190f, 1.000000f, 1.000000f }, 
+         { 0.492063f, 0.000000f, 0.000000f }, 
+         { 0.507937f, 0.000000f, 0.000000f }, 
+         { 0.523810f, 1.000000f, 1.000000f }, 
+         { 0.539683f, 1.000000f, 1.000000f }, 
+         { 0.555556f, 0.000000f, 0.000000f }, 
+         { 0.571429f, 0.000000f, 0.000000f }, 
+         { 0.587302f, 1.000000f, 1.000000f }, 
+         { 0.603175f, 1.000000f, 1.000000f }, 
+         { 0.619048f, 0.000000f, 0.000000f }, 
+         { 0.634921f, 0.000000f, 0.000000f }, 
+         { 0.650794f, 1.000000f, 1.000000f }, 
+         { 0.666667f, 1.000000f, 1.000000f }, 
+         { 0.682540f, 0.000000f, 0.000000f }, 
+         { 0.698413f, 0.000000f, 0.000000f }, 
+         { 0.714286f, 1.000000f, 1.000000f }, 
+         { 0.730159f, 1.000000f, 1.000000f }, 
+         { 0.746032f, 0.000000f, 0.000000f }, 
+         { 0.761905f, 0.000000f, 0.000000f }, 
+         { 0.777778f, 1.000000f, 1.000000f }, 
+         { 0.793651f, 1.000000f, 1.000000f }, 
+         { 0.809524f, 0.000000f, 0.000000f }, 
+         { 0.825397f, 0.000000f, 0.000000f }, 
+         { 0.841270f, 1.000000f, 1.000000f }, 
+         { 0.857143f, 1.000000f, 1.000000f }, 
+         { 0.873016f, 0.000000f, 0.000000f }, 
+         { 0.888889f, 0.000000f, 0.000000f }, 
+         { 0.904762f, 1.000000f, 1.000000f }, 
+         { 0.920635f, 1.000000f, 1.000000f }, 
+         { 0.936508f, 0.000000f, 0.000000f }, 
+         { 0.952381f, 0.000000f, 0.000000f }, 
+         { 0.968254f, 1.000000f, 1.000000f }, 
+         { 0.984127f, 1.000000f, 1.000000f }, 
+         { 1.000000f, 0.000000f, 0.000000f } } 
+       };
+
+       /**
+        * Specification for the "hot" color map.
+        */
+       private static final float[][][] SPEC_HOT = {
+       { // R
+         { 0.000000f, 0.041600f, 0.041600f }, 
+         { 0.365079f, 1.000000f, 1.000000f }, 
+         { 1.000000f, 1.000000f, 1.000000f } }, 
+       { // G
+         { 0.000000f, 0.000000f, 0.000000f }, 
+         { 0.365079f, 0.000000f, 0.000000f }, 
+         { 0.746032f, 1.000000f, 1.000000f }, 
+         { 1.000000f, 1.000000f, 1.000000f } }, 
+       { // B
+         { 0.000000f, 0.000000f, 0.000000f }, 
+         { 0.746032f, 0.000000f, 0.000000f }, 
+         { 1.000000f, 1.000000f, 1.000000f } } 
+       };
+
+       /**
+        * Specification for the "jet" color map.
+        */
+       private static final float[][][] SPEC_JET = {
+       { // R
+         { 0.000000f, 0.000000f, 0.000000f }, 
+         { 0.350000f, 0.000000f, 0.000000f }, 
+         { 0.660000f, 1.000000f, 1.000000f }, 
+         { 0.890000f, 1.000000f, 1.000000f }, 
+         { 1.000000f, 0.500000f, 0.500000f } }, 
+       { // G
+         { 0.000000f, 0.000000f, 0.000000f }, 
+         { 0.125000f, 0.000000f, 0.000000f }, 
+         { 0.375000f, 1.000000f, 1.000000f }, 
+         { 0.640000f, 1.000000f, 1.000000f }, 
+         { 0.910000f, 0.000000f, 0.000000f }, 
+         { 1.000000f, 0.000000f, 0.000000f } }, 
+       { // B
+         { 0.000000f, 0.500000f, 0.500000f }, 
+         { 0.110000f, 1.000000f, 1.000000f }, 
+         { 0.340000f, 1.000000f, 1.000000f }, 
+         { 0.650000f, 0.000000f, 0.000000f }, 
+         { 1.000000f, 0.000000f, 0.000000f } } 
+       };
+
+       /**
+        * Specification for the "pink" color map.
+        */
+       private static final float[][][] SPEC_PINK = {
+       { // R
+         { 0.000000f, 0.117800f, 0.117800f }, 
+         { 0.015873f, 0.195857f, 0.195857f }, 
+         { 0.031746f, 0.250661f, 0.250661f }, 
+         { 0.047619f, 0.295468f, 0.295468f }, 
+         { 0.063492f, 0.334324f, 0.334324f }, 
+         { 0.079365f, 0.369112f, 0.369112f }, 
+         { 0.095238f, 0.400892f, 0.400892f }, 
+         { 0.111111f, 0.430331f, 0.430331f }, 
+         { 0.126984f, 0.457882f, 0.457882f }, 
+         { 0.142857f, 0.483867f, 0.483867f }, 
+         { 0.158730f, 0.508525f, 0.508525f }, 
+         { 0.174603f, 0.532042f, 0.532042f }, 
+         { 0.190476f, 0.554563f, 0.554563f }, 
+         { 0.206349f, 0.576204f, 0.576204f }, 
+         { 0.222222f, 0.597061f, 0.597061f }, 
+         { 0.238095f, 0.617213f, 0.617213f }, 
+         { 0.253968f, 0.636729f, 0.636729f }, 
+         { 0.269841f, 0.655663f, 0.655663f }, 
+         { 0.285714f, 0.674066f, 0.674066f }, 
+         { 0.301587f, 0.691980f, 0.691980f }, 
+         { 0.317460f, 0.709441f, 0.709441f }, 
+         { 0.333333f, 0.726483f, 0.726483f }, 
+         { 0.349206f, 0.743134f, 0.743134f }, 
+         { 0.365079f, 0.759421f, 0.759421f }, 
+         { 0.380952f, 0.766356f, 0.766356f }, 
+         { 0.396825f, 0.773229f, 0.773229f }, 
+         { 0.412698f, 0.780042f, 0.780042f }, 
+         { 0.428571f, 0.786796f, 0.786796f }, 
+         { 0.444444f, 0.793492f, 0.793492f }, 
+         { 0.460317f, 0.800132f, 0.800132f }, 
+         { 0.476190f, 0.806718f, 0.806718f }, 
+         { 0.492063f, 0.813250f, 0.813250f }, 
+         { 0.507937f, 0.819730f, 0.819730f }, 
+         { 0.523810f, 0.826160f, 0.826160f }, 
+         { 0.539683f, 0.832539f, 0.832539f }, 
+         { 0.555556f, 0.838870f, 0.838870f }, 
+         { 0.571429f, 0.845154f, 0.845154f }, 
+         { 0.587302f, 0.851392f, 0.851392f }, 
+         { 0.603175f, 0.857584f, 0.857584f }, 
+         { 0.619048f, 0.863731f, 0.863731f }, 
+         { 0.634921f, 0.869835f, 0.869835f }, 
+         { 0.650794f, 0.875897f, 0.875897f }, 
+         { 0.666667f, 0.881917f, 0.881917f }, 
+         { 0.682540f, 0.887896f, 0.887896f }, 
+         { 0.698413f, 0.893835f, 0.893835f }, 
+         { 0.714286f, 0.899735f, 0.899735f }, 
+         { 0.730159f, 0.905597f, 0.905597f }, 
+         { 0.746032f, 0.911421f, 0.911421f }, 
+         { 0.761905f, 0.917208f, 0.917208f }, 
+         { 0.777778f, 0.922958f, 0.922958f }, 
+         { 0.793651f, 0.928673f, 0.928673f }, 
+         { 0.809524f, 0.934353f, 0.934353f }, 
+         { 0.825397f, 0.939999f, 0.939999f }, 
+         { 0.841270f, 0.945611f, 0.945611f }, 
+         { 0.857143f, 0.951190f, 0.951190f }, 
+         { 0.873016f, 0.956736f, 0.956736f }, 
+         { 0.888889f, 0.962250f, 0.962250f }, 
+         { 0.904762f, 0.967733f, 0.967733f }, 
+         { 0.920635f, 0.973185f, 0.973185f }, 
+         { 0.936508f, 0.978607f, 0.978607f }, 
+         { 0.952381f, 0.983999f, 0.983999f }, 
+         { 0.968254f, 0.989361f, 0.989361f }, 
+         { 0.984127f, 0.994695f, 0.994695f }, 
+         { 1.000000f, 1.000000f, 1.000000f } }, 
+       { // G
+         { 0.000000f, 0.000000f, 0.000000f }, 
+         { 0.015873f, 0.102869f, 0.102869f }, 
+         { 0.031746f, 0.145479f, 0.145479f }, 
+         { 0.047619f, 0.178174f, 0.178174f }, 
+         { 0.063492f, 0.205738f, 0.205738f }, 
+         { 0.079365f, 0.230022f, 0.230022f }, 
+         { 0.095238f, 0.251976f, 0.251976f }, 
+         { 0.111111f, 0.272166f, 0.272166f }, 
+         { 0.126984f, 0.290957f, 0.290957f }, 
+         { 0.142857f, 0.308607f, 0.308607f }, 
+         { 0.158730f, 0.325300f, 0.325300f }, 
+         { 0.174603f, 0.341178f, 0.341178f }, 
+         { 0.190476f, 0.356348f, 0.356348f }, 
+         { 0.206349f, 0.370899f, 0.370899f }, 
+         { 0.222222f, 0.384900f, 0.384900f }, 
+         { 0.238095f, 0.398410f, 0.398410f }, 
+         { 0.253968f, 0.411476f, 0.411476f }, 
+         { 0.269841f, 0.424139f, 0.424139f }, 
+         { 0.285714f, 0.436436f, 0.436436f }, 
+         { 0.301587f, 0.448395f, 0.448395f }, 
+         { 0.317460f, 0.460044f, 0.460044f }, 
+         { 0.333333f, 0.471405f, 0.471405f }, 
+         { 0.349206f, 0.482498f, 0.482498f }, 
+         { 0.365079f, 0.493342f, 0.493342f }, 
+         { 0.380952f, 0.517549f, 0.517549f }, 
+         { 0.396825f, 0.540674f, 0.540674f }, 
+         { 0.412698f, 0.562849f, 0.562849f }, 
+         { 0.428571f, 0.584183f, 0.584183f }, 
+         { 0.444444f, 0.604765f, 0.604765f }, 
+         { 0.460317f, 0.624669f, 0.624669f }, 
+         { 0.476190f, 0.643958f, 0.643958f }, 
+         { 0.492063f, 0.662687f, 0.662687f }, 
+         { 0.507937f, 0.680900f, 0.680900f }, 
+         { 0.523810f, 0.698638f, 0.698638f }, 
+         { 0.539683f, 0.715937f, 0.715937f }, 
+         { 0.555556f, 0.732828f, 0.732828f }, 
+         { 0.571429f, 0.749338f, 0.749338f }, 
+         { 0.587302f, 0.765493f, 0.765493f }, 
+         { 0.603175f, 0.781313f, 0.781313f }, 
+         { 0.619048f, 0.796819f, 0.796819f }, 
+         { 0.634921f, 0.812029f, 0.812029f }, 
+         { 0.650794f, 0.826960f, 0.826960f }, 
+         { 0.666667f, 0.841625f, 0.841625f }, 
+         { 0.682540f, 0.856040f, 0.856040f }, 
+         { 0.698413f, 0.870216f, 0.870216f }, 
+         { 0.714286f, 0.884164f, 0.884164f }, 
+         { 0.730159f, 0.897896f, 0.897896f }, 
+         { 0.746032f, 0.911421f, 0.911421f }, 
+         { 0.761905f, 0.917208f, 0.917208f }, 
+         { 0.777778f, 0.922958f, 0.922958f }, 
+         { 0.793651f, 0.928673f, 0.928673f }, 
+         { 0.809524f, 0.934353f, 0.934353f }, 
+         { 0.825397f, 0.939999f, 0.939999f }, 
+         { 0.841270f, 0.945611f, 0.945611f }, 
+         { 0.857143f, 0.951190f, 0.951190f }, 
+         { 0.873016f, 0.956736f, 0.956736f }, 
+         { 0.888889f, 0.962250f, 0.962250f }, 
+         { 0.904762f, 0.967733f, 0.967733f }, 
+         { 0.920635f, 0.973185f, 0.973185f }, 
+         { 0.936508f, 0.978607f, 0.978607f }, 
+         { 0.952381f, 0.983999f, 0.983999f }, 
+         { 0.968254f, 0.989361f, 0.989361f }, 
+         { 0.984127f, 0.994695f, 0.994695f }, 
+         { 1.000000f, 1.000000f, 1.000000f } }, 
+       { // B
+         { 0.000000f, 0.000000f, 0.000000f }, 
+         { 0.015873f, 0.102869f, 0.102869f }, 
+         { 0.031746f, 0.145479f, 0.145479f }, 
+         { 0.047619f, 0.178174f, 0.178174f }, 
+         { 0.063492f, 0.205738f, 0.205738f }, 
+         { 0.079365f, 0.230022f, 0.230022f }, 
+         { 0.095238f, 0.251976f, 0.251976f }, 
+         { 0.111111f, 0.272166f, 0.272166f }, 
+         { 0.126984f, 0.290957f, 0.290957f }, 
+         { 0.142857f, 0.308607f, 0.308607f }, 
+         { 0.158730f, 0.325300f, 0.325300f }, 
+         { 0.174603f, 0.341178f, 0.341178f }, 
+         { 0.190476f, 0.356348f, 0.356348f }, 
+         { 0.206349f, 0.370899f, 0.370899f }, 
+         { 0.222222f, 0.384900f, 0.384900f }, 
+         { 0.238095f, 0.398410f, 0.398410f }, 
+         { 0.253968f, 0.411476f, 0.411476f }, 
+         { 0.269841f, 0.424139f, 0.424139f }, 
+         { 0.285714f, 0.436436f, 0.436436f }, 
+         { 0.301587f, 0.448395f, 0.448395f }, 
+         { 0.317460f, 0.460044f, 0.460044f }, 
+         { 0.333333f, 0.471405f, 0.471405f }, 
+         { 0.349206f, 0.482498f, 0.482498f }, 
+         { 0.365079f, 0.493342f, 0.493342f }, 
+         { 0.380952f, 0.503953f, 0.503953f }, 
+         { 0.396825f, 0.514344f, 0.514344f }, 
+         { 0.412698f, 0.524531f, 0.524531f }, 
+         { 0.428571f, 0.534522f, 0.534522f }, 
+         { 0.444444f, 0.544331f, 0.544331f }, 
+         { 0.460317f, 0.553966f, 0.553966f }, 
+         { 0.476190f, 0.563436f, 0.563436f }, 
+         { 0.492063f, 0.572750f, 0.572750f }, 
+         { 0.507937f, 0.581914f, 0.581914f }, 
+         { 0.523810f, 0.590937f, 0.590937f }, 
+         { 0.539683f, 0.599824f, 0.599824f }, 
+         { 0.555556f, 0.608581f, 0.608581f }, 
+         { 0.571429f, 0.617213f, 0.617213f }, 
+         { 0.587302f, 0.625727f, 0.625727f }, 
+         { 0.603175f, 0.634126f, 0.634126f }, 
+         { 0.619048f, 0.642416f, 0.642416f }, 
+         { 0.634921f, 0.650600f, 0.650600f }, 
+         { 0.650794f, 0.658682f, 0.658682f }, 
+         { 0.666667f, 0.666667f, 0.666667f }, 
+         { 0.682540f, 0.674556f, 0.674556f }, 
+         { 0.698413f, 0.682355f, 0.682355f }, 
+         { 0.714286f, 0.690066f, 0.690066f }, 
+         { 0.730159f, 0.697691f, 0.697691f }, 
+         { 0.746032f, 0.705234f, 0.705234f }, 
+         { 0.761905f, 0.727166f, 0.727166f }, 
+         { 0.777778f, 0.748455f, 0.748455f }, 
+         { 0.793651f, 0.769156f, 0.769156f }, 
+         { 0.809524f, 0.789314f, 0.789314f }, 
+         { 0.825397f, 0.808969f, 0.808969f }, 
+         { 0.841270f, 0.828159f, 0.828159f }, 
+         { 0.857143f, 0.846913f, 0.846913f }, 
+         { 0.873016f, 0.865261f, 0.865261f }, 
+         { 0.888889f, 0.883229f, 0.883229f }, 
+         { 0.904762f, 0.900837f, 0.900837f }, 
+         { 0.920635f, 0.918109f, 0.918109f }, 
+         { 0.936508f, 0.935061f, 0.935061f }, 
+         { 0.952381f, 0.951711f, 0.951711f }, 
+         { 0.968254f, 0.968075f, 0.968075f }, 
+         { 0.984127f, 0.984167f, 0.984167f }, 
+         { 1.000000f, 1.000000f, 1.000000f } } 
+       };
+
+       /**
+        * Specification for the "prism" color map.
+        */
+       private static final float[][][] SPEC_PRISM = {
+       { // R
+         { 0.000000f, 1.000000f, 1.000000f }, 
+         { 0.031746f, 1.000000f, 1.000000f }, 
+         { 0.047619f, 0.000000f, 0.000000f }, 
+         { 0.063492f, 0.000000f, 0.000000f }, 
+         { 0.079365f, 0.666667f, 0.666667f }, 
+         { 0.095238f, 1.000000f, 1.000000f }, 
+         { 0.126984f, 1.000000f, 1.000000f }, 
+         { 0.142857f, 0.000000f, 0.000000f }, 
+         { 0.158730f, 0.000000f, 0.000000f }, 
+         { 0.174603f, 0.666667f, 0.666667f }, 
+         { 0.190476f, 1.000000f, 1.000000f }, 
+         { 0.222222f, 1.000000f, 1.000000f }, 
+         { 0.238095f, 0.000000f, 0.000000f }, 
+         { 0.253968f, 0.000000f, 0.000000f }, 
+         { 0.269841f, 0.666667f, 0.666667f }, 
+         { 0.285714f, 1.000000f, 1.000000f }, 
+         { 0.317460f, 1.000000f, 1.000000f }, 
+         { 0.333333f, 0.000000f, 0.000000f }, 
+         { 0.349206f, 0.000000f, 0.000000f }, 
+         { 0.365079f, 0.666667f, 0.666667f }, 
+         { 0.380952f, 1.000000f, 1.000000f }, 
+         { 0.412698f, 1.000000f, 1.000000f }, 
+         { 0.428571f, 0.000000f, 0.000000f }, 
+         { 0.444444f, 0.000000f, 0.000000f }, 
+         { 0.460317f, 0.666667f, 0.666667f }, 
+         { 0.476190f, 1.000000f, 1.000000f }, 
+         { 0.507937f, 1.000000f, 1.000000f }, 
+         { 0.523810f, 0.000000f, 0.000000f }, 
+         { 0.539683f, 0.000000f, 0.000000f }, 
+         { 0.555556f, 0.666667f, 0.666667f }, 
+         { 0.571429f, 1.000000f, 1.000000f }, 
+         { 0.603175f, 1.000000f, 1.000000f }, 
+         { 0.619048f, 0.000000f, 0.000000f }, 
+         { 0.634921f, 0.000000f, 0.000000f }, 
+         { 0.650794f, 0.666667f, 0.666667f }, 
+         { 0.666667f, 1.000000f, 1.000000f }, 
+         { 0.698413f, 1.000000f, 1.000000f }, 
+         { 0.714286f, 0.000000f, 0.000000f }, 
+         { 0.730159f, 0.000000f, 0.000000f }, 
+         { 0.746032f, 0.666667f, 0.666667f }, 
+         { 0.761905f, 1.000000f, 1.000000f }, 
+         { 0.793651f, 1.000000f, 1.000000f }, 
+         { 0.809524f, 0.000000f, 0.000000f }, 
+         { 0.825397f, 0.000000f, 0.000000f }, 
+         { 0.841270f, 0.666667f, 0.666667f }, 
+         { 0.857143f, 1.000000f, 1.000000f }, 
+         { 0.888889f, 1.000000f, 1.000000f }, 
+         { 0.904762f, 0.000000f, 0.000000f }, 
+         { 0.920635f, 0.000000f, 0.000000f }, 
+         { 0.936508f, 0.666667f, 0.666667f }, 
+         { 0.952381f, 1.000000f, 1.000000f }, 
+         { 0.984127f, 1.000000f, 1.000000f }, 
+         { 1.000000f, 0.000000f, 0.000000f } }, 
+       { // G
+         { 0.000000f, 0.000000f, 0.000000f }, 
+         { 0.031746f, 1.000000f, 1.000000f }, 
+         { 0.047619f, 1.000000f, 1.000000f }, 
+         { 0.063492f, 0.000000f, 0.000000f }, 
+         { 0.095238f, 0.000000f, 0.000000f }, 
+         { 0.126984f, 1.000000f, 1.000000f }, 
+         { 0.142857f, 1.000000f, 1.000000f }, 
+         { 0.158730f, 0.000000f, 0.000000f }, 
+         { 0.190476f, 0.000000f, 0.000000f }, 
+         { 0.222222f, 1.000000f, 1.000000f }, 
+         { 0.238095f, 1.000000f, 1.000000f }, 
+         { 0.253968f, 0.000000f, 0.000000f }, 
+         { 0.285714f, 0.000000f, 0.000000f }, 
+         { 0.317460f, 1.000000f, 1.000000f }, 
+         { 0.333333f, 1.000000f, 1.000000f }, 
+         { 0.349206f, 0.000000f, 0.000000f }, 
+         { 0.380952f, 0.000000f, 0.000000f }, 
+         { 0.412698f, 1.000000f, 1.000000f }, 
+         { 0.428571f, 1.000000f, 1.000000f }, 
+         { 0.444444f, 0.000000f, 0.000000f }, 
+         { 0.476190f, 0.000000f, 0.000000f }, 
+         { 0.507937f, 1.000000f, 1.000000f }, 
+         { 0.523810f, 1.000000f, 1.000000f }, 
+         { 0.539683f, 0.000000f, 0.000000f }, 
+         { 0.571429f, 0.000000f, 0.000000f }, 
+         { 0.603175f, 1.000000f, 1.000000f }, 
+         { 0.619048f, 1.000000f, 1.000000f }, 
+         { 0.634921f, 0.000000f, 0.000000f }, 
+         { 0.666667f, 0.000000f, 0.000000f }, 
+         { 0.698413f, 1.000000f, 1.000000f }, 
+         { 0.714286f, 1.000000f, 1.000000f }, 
+         { 0.730159f, 0.000000f, 0.000000f }, 
+         { 0.761905f, 0.000000f, 0.000000f }, 
+         { 0.793651f, 1.000000f, 1.000000f }, 
+         { 0.809524f, 1.000000f, 1.000000f }, 
+         { 0.825397f, 0.000000f, 0.000000f }, 
+         { 0.857143f, 0.000000f, 0.000000f }, 
+         { 0.888889f, 1.000000f, 1.000000f }, 
+         { 0.904762f, 1.000000f, 1.000000f }, 
+         { 0.920635f, 0.000000f, 0.000000f }, 
+         { 0.952381f, 0.000000f, 0.000000f }, 
+         { 0.984127f, 1.000000f, 1.000000f }, 
+         { 1.000000f, 1.000000f, 1.000000f } }, 
+       { // B
+         { 0.000000f, 0.000000f, 0.000000f }, 
+         { 0.047619f, 0.000000f, 0.000000f }, 
+         { 0.063492f, 1.000000f, 1.000000f }, 
+         { 0.079365f, 1.000000f, 1.000000f }, 
+         { 0.095238f, 0.000000f, 0.000000f }, 
+         { 0.142857f, 0.000000f, 0.000000f }, 
+         { 0.158730f, 1.000000f, 1.000000f }, 
+         { 0.174603f, 1.000000f, 1.000000f }, 
+         { 0.190476f, 0.000000f, 0.000000f }, 
+         { 0.238095f, 0.000000f, 0.000000f }, 
+         { 0.253968f, 1.000000f, 1.000000f }, 
+         { 0.269841f, 1.000000f, 1.000000f }, 
+         { 0.285714f, 0.000000f, 0.000000f }, 
+         { 0.333333f, 0.000000f, 0.000000f }, 
+         { 0.349206f, 1.000000f, 1.000000f }, 
+         { 0.365079f, 1.000000f, 1.000000f }, 
+         { 0.380952f, 0.000000f, 0.000000f }, 
+         { 0.428571f, 0.000000f, 0.000000f }, 
+         { 0.444444f, 1.000000f, 1.000000f }, 
+         { 0.460317f, 1.000000f, 1.000000f }, 
+         { 0.476190f, 0.000000f, 0.000000f }, 
+         { 0.523810f, 0.000000f, 0.000000f }, 
+         { 0.539683f, 1.000000f, 1.000000f }, 
+         { 0.555556f, 1.000000f, 1.000000f }, 
+         { 0.571429f, 0.000000f, 0.000000f }, 
+         { 0.619048f, 0.000000f, 0.000000f }, 
+         { 0.634921f, 1.000000f, 1.000000f }, 
+         { 0.650794f, 1.000000f, 1.000000f }, 
+         { 0.666667f, 0.000000f, 0.000000f }, 
+         { 0.714286f, 0.000000f, 0.000000f }, 
+         { 0.730159f, 1.000000f, 1.000000f }, 
+         { 0.746032f, 1.000000f, 1.000000f }, 
+         { 0.761905f, 0.000000f, 0.000000f }, 
+         { 0.809524f, 0.000000f, 0.000000f }, 
+         { 0.825397f, 1.000000f, 1.000000f }, 
+         { 0.841270f, 1.000000f, 1.000000f }, 
+         { 0.857143f, 0.000000f, 0.000000f }, 
+         { 0.904762f, 0.000000f, 0.000000f }, 
+         { 0.920635f, 1.000000f, 1.000000f }, 
+         { 0.936508f, 1.000000f, 1.000000f }, 
+         { 0.952381f, 0.000000f, 0.000000f }, 
+         { 1.000000f, 0.000000f, 0.000000f } } 
+       };
+
+       /**
+        * Specification for the "spring" color map.
+        */
+       private static final float[][][] SPEC_SPRING = {
+       { // R
+         { 0.000000f, 1.000000f, 1.000000f }, 
+         { 1.000000f, 1.000000f, 1.000000f } }, 
+       { // G
+         { 0.000000f, 0.000000f, 0.000000f }, 
+         { 1.000000f, 1.000000f, 1.000000f } }, 
+       { // B
+         { 0.000000f, 1.000000f, 1.000000f }, 
+         { 1.000000f, 0.000000f, 0.000000f } } 
+       };
+
+       /**
+        * Specification for the "summer" color map.
+        */
+       private static final float[][][] SPEC_SUMMER = {
+       { // R
+         { 0.000000f, 0.000000f, 0.000000f }, 
+         { 1.000000f, 1.000000f, 1.000000f } }, 
+       { // G
+         { 0.000000f, 0.500000f, 0.500000f }, 
+         { 1.000000f, 1.000000f, 1.000000f } }, 
+       { // B
+         { 0.000000f, 0.400000f, 0.400000f }, 
+         { 1.000000f, 0.400000f, 0.400000f } } 
+       };
+
+       /**
+        * Specification for the "winter" color map.
+        */
+       private static final float[][][] SPEC_WINTER = {
+       { // R
+         { 0.000000f, 0.000000f, 0.000000f }, 
+         { 1.000000f, 0.000000f, 0.000000f } }, 
+       { // G
+         { 0.000000f, 0.000000f, 0.000000f }, 
+         { 1.000000f, 1.000000f, 1.000000f } }, 
+       { // B
+         { 0.000000f, 1.000000f, 1.000000f }, 
+         { 1.000000f, 0.500000f, 0.500000f } } 
+       };
+
+       /**
+        * Specification for the "spectral" color map.
+        */
+       private static final float[][][] SPEC_SPECTRAL = {
+       { // R
+         { 0.000000f, 0.000000f, 0.000000f }, 
+         { 0.050000f, 0.466700f, 0.466700f }, 
+         { 0.100000f, 0.533300f, 0.533300f }, 
+         { 0.150000f, 0.000000f, 0.000000f }, 
+         { 0.200000f, 0.000000f, 0.000000f }, 
+         { 0.250000f, 0.000000f, 0.000000f }, 
+         { 0.300000f, 0.000000f, 0.000000f }, 
+         { 0.350000f, 0.000000f, 0.000000f }, 
+         { 0.400000f, 0.000000f, 0.000000f }, 
+         { 0.450000f, 0.000000f, 0.000000f }, 
+         { 0.500000f, 0.000000f, 0.000000f }, 
+         { 0.550000f, 0.000000f, 0.000000f }, 
+         { 0.600000f, 0.000000f, 0.000000f }, 
+         { 0.650000f, 0.733300f, 0.733300f }, 
+         { 0.700000f, 0.933300f, 0.933300f }, 
+         { 0.750000f, 1.000000f, 1.000000f }, 
+         { 0.800000f, 1.000000f, 1.000000f }, 
+         { 0.850000f, 1.000000f, 1.000000f }, 
+         { 0.900000f, 0.866700f, 0.866700f }, 
+         { 0.950000f, 0.800000f, 0.800000f }, 
+         { 1.000000f, 0.800000f, 0.800000f } }, 
+       { // G
+         { 0.000000f, 0.000000f, 0.000000f }, 
+         { 0.050000f, 0.000000f, 0.000000f }, 
+         { 0.100000f, 0.000000f, 0.000000f }, 
+         { 0.150000f, 0.000000f, 0.000000f }, 
+         { 0.200000f, 0.000000f, 0.000000f }, 
+         { 0.250000f, 0.466700f, 0.466700f }, 
+         { 0.300000f, 0.600000f, 0.600000f }, 
+         { 0.350000f, 0.666700f, 0.666700f }, 
+         { 0.400000f, 0.666700f, 0.666700f }, 
+         { 0.450000f, 0.600000f, 0.600000f }, 
+         { 0.500000f, 0.733300f, 0.733300f }, 
+         { 0.550000f, 0.866700f, 0.866700f }, 
+         { 0.600000f, 1.000000f, 1.000000f }, 
+         { 0.650000f, 1.000000f, 1.000000f }, 
+         { 0.700000f, 0.933300f, 0.933300f }, 
+         { 0.750000f, 0.800000f, 0.800000f }, 
+         { 0.800000f, 0.600000f, 0.600000f }, 
+         { 0.850000f, 0.000000f, 0.000000f }, 
+         { 0.900000f, 0.000000f, 0.000000f }, 
+         { 0.950000f, 0.000000f, 0.000000f }, 
+         { 1.000000f, 0.800000f, 0.800000f } }, 
+       { // B
+         { 0.000000f, 0.000000f, 0.000000f }, 
+         { 0.050000f, 0.533300f, 0.533300f }, 
+         { 0.100000f, 0.600000f, 0.600000f }, 
+         { 0.150000f, 0.666700f, 0.666700f }, 
+         { 0.200000f, 0.866700f, 0.866700f }, 
+         { 0.250000f, 0.866700f, 0.866700f }, 
+         { 0.300000f, 0.866700f, 0.866700f }, 
+         { 0.350000f, 0.666700f, 0.666700f }, 
+         { 0.400000f, 0.533300f, 0.533300f }, 
+         { 0.450000f, 0.000000f, 0.000000f }, 
+         { 0.500000f, 0.000000f, 0.000000f }, 
+         { 0.550000f, 0.000000f, 0.000000f }, 
+         { 0.600000f, 0.000000f, 0.000000f }, 
+         { 0.650000f, 0.000000f, 0.000000f }, 
+         { 0.700000f, 0.000000f, 0.000000f }, 
+         { 0.750000f, 0.000000f, 0.000000f }, 
+         { 0.800000f, 0.000000f, 0.000000f }, 
+         { 0.850000f, 0.000000f, 0.000000f }, 
+         { 0.900000f, 0.000000f, 0.000000f }, 
+         { 0.950000f, 0.000000f, 0.000000f }, 
+         { 1.000000f, 0.800000f, 0.800000f } } 
+       };
+       
+       private static class SpecCache {
+               final float[][][] spec;
+               ColorMap map;
+       
+               SpecCache(float[][][] spec) {
+                       this.spec = spec;
+               }
+       };
+       
+       private static final Map<String, SpecCache> cache = 
+               new HashMap<String, SpecCache>();
+       
+       static {
+               cache.put("binary", new SpecCache(SPEC_BINARY));
+               cache.put("grey", new SpecCache(SPEC_GREY));
+               cache.put("autumn", new SpecCache(SPEC_AUTUMN));
+               cache.put("bone", new SpecCache(SPEC_BONE));
+               cache.put("cool", new SpecCache(SPEC_COOL));
+               cache.put("copper", new SpecCache(SPEC_COPPER));
+               cache.put("flag", new SpecCache(SPEC_FLAG));
+               cache.put("hot", new SpecCache(SPEC_HOT));
+               cache.put("jet", new SpecCache(SPEC_JET));
+               cache.put("pink", new SpecCache(SPEC_PINK));
+               cache.put("prism", new SpecCache(SPEC_PRISM));
+               cache.put("spring", new SpecCache(SPEC_SPRING));
+               cache.put("summer", new SpecCache(SPEC_SUMMER));
+               cache.put("winter", new SpecCache(SPEC_WINTER));
+               cache.put("spectral", new SpecCache(SPEC_SPECTRAL));
+       }
+       
+       /**
+        * Size of the predefined maps returned by this class
+        */
+       public static final int MAP_SIZE = 256;
+       
+       /**
+        * Returns the (unmodifiable) set of predefined map names.
+        */
+       public static Set<String> names() {
+               return Collections.unmodifiableSet(cache.keySet());
+       }
+       
+       /**
+        * Get a color map by name.
+        * 
+        * @param name
+        *            The color map names
+        * @return The color map.
+        */
+       public static ColorMap get(String name) {
+               if (cache.containsKey(name)) {
+                       SpecCache item = cache.get(name);
+                       if (item.map == null) {
+                               item.map = new LinearColorMap(MAP_SIZE, item.spec);
+                       }
+                       return item.map;
+               }
+               return null;
+       }
+       
+       /**
+        * Returns the "binary" color map
+        */
+       public static ColorMap binary() {
+           return get("binary");
+       }
+       
+       /**
+        * Returns the "grey" color map
+        */
+       public static ColorMap grey() {
+           return get("grey");
+       }
+
+       /**
+        * Returns the "autumn" color map
+        */
+       public static ColorMap autumn() {
+           return get("autumn");
+       }
+
+       /**
+        * Returns the "bone" color map
+        */
+       public static ColorMap bone() {
+           return get("bone");
+       }
+
+       /**
+        * Returns the "cool" color map
+        */
+       public static ColorMap cool() {
+           return get("cool");
+       }
+
+       /**
+        * Returns the "copper" color map
+        */
+       public static ColorMap copper() {
+           return get("copper");
+       }
+
+       /**
+        * Returns the "flag" color map
+        */
+       public static ColorMap flag() {
+           return get("flag");
+       }
+
+       /**
+        * Returns the "hot" color map
+        */
+       public static ColorMap hot() {
+           return get("hot");
+       }
+
+       /**
+        * Returns the "jet" color map
+        */
+       public static ColorMap jet() {
+           return get("jet");
+       }
+
+       /**
+        * Returns the "pink" color map
+        */
+       public static ColorMap pink() {
+           return get("pink");
+       }
+
+       /**
+        * Returns the "prism" color map
+        */
+       public static ColorMap prism() {
+           return get("prism");
+       }
+
+       /**
+        * Returns the "spring" color map
+        */
+       public static ColorMap spring() {
+           return get("spring");
+       }
+
+       /**
+        * Returns the "summer" color map
+        */
+       public static ColorMap summer() {
+           return get("summer");
+       }
+
+       /**
+        * Returns the "winter" color map
+        */
+       public static ColorMap winter() {
+           return get("winter");
+       }
+
+       /**
+        * Returns the "spectral" color map
+        */
+       public static ColorMap spectral() {
+           return get("spectral");
+       }
+}
diff --git a/Annotation/src/ie/dcu/image/colormap/LinearColorMap.class b/Annotation/src/ie/dcu/image/colormap/LinearColorMap.class
new file mode 100644 (file)
index 0000000..e0ea566
Binary files /dev/null and b/Annotation/src/ie/dcu/image/colormap/LinearColorMap.class differ
diff --git a/Annotation/src/ie/dcu/image/colormap/LinearColorMap.java b/Annotation/src/ie/dcu/image/colormap/LinearColorMap.java
new file mode 100644 (file)
index 0000000..fbddfd7
--- /dev/null
@@ -0,0 +1,110 @@
+package ie.dcu.image.colormap;
+
+import java.util.Arrays;
+
+/**
+ * A linear segment color map.
+ * 
+ * @author Kevin McGuinness
+ */
+public class LinearColorMap extends ColorMap {
+       
+       private static final long serialVersionUID = -7024754461124096870L;
+
+       public LinearColorMap(int size, 
+                       float[][] rspec, 
+                       float[][] gspec, 
+                       float[][] bspec) 
+       {
+               super(size); // me :-P
+               
+               float[] rvals = mapping(size, rspec);
+               for (int i = 0; i < size; i++) {
+                       lut[i][0] = rvals[i];
+               }
+               
+               float[] gvals = mapping(size, gspec);
+               for (int i = 0; i < size; i++) {
+                       lut[i][1] = gvals[i];
+               }
+               
+               float[] bvals = mapping(size, bspec);
+               for (int i = 0; i < size; i++) {
+                       lut[i][2] = bvals[i];
+               }
+       }
+       
+       public LinearColorMap(int size, float[][][] spec) {
+               this(size, spec[0], spec[1], spec[2]);
+       }
+       
+       private static float[] mapping(int n, float[][] spec) {
+               final int X  = 0;
+               final int Y0 = 1;
+               final int Y1 = 2;
+               
+               // Non null
+               if (spec == null) {
+                       throw new NullPointerException();
+               }
+               
+               // Non empty
+               if (spec.length == 0) {
+                       throw new IllegalArgumentException("spec empty");
+               }
+               
+               // Number of cols must be 3
+               for (int i = 0; i < spec.length; i++) {
+                       if (spec[i].length != 3) {
+                               throw new IllegalArgumentException("number of cols must be 3");
+                       }
+               }
+               
+               // X value must start at zero and end at 1
+               if (spec[0][X] != 0.0 || spec[spec.length-1][X] != 1.0) {
+                       throw new IllegalArgumentException("x value must start at zero and end at 1");
+               }
+               
+               // X value must be increasing
+               for (int i = 1; i < spec.length; i++) {
+                       if (spec[i][X] < spec[i-1][X]) {
+                               throw new IllegalArgumentException("x value must be increasing");
+                       }
+               }
+               
+               float[] lut = new float[n];
+               Arrays.fill(lut, 0.0f);
+               
+               lut[0] = clip(spec[0][Y1]);
+               
+               // x values by 255
+               float[] x = new float[spec.length];
+               for (int i = 0; i < spec.length; i++) {
+                       x[i] = spec[i][X] * (n-1);
+               }
+               
+               // Indices
+               int[] idx = new int[n];
+               for (int i = 0, j = 0; i < n; i++) {
+                       while (j != x.length && x[j] < i) {
+                               j++;
+                       }
+                       idx[i] = j;
+               }
+               
+               for (int i = 1; i < n-1; i++) {
+                       float v = ((i - x[idx[i]-1]) / (x[idx[i]] - x[idx[i]-1])) 
+                               * (spec[idx[i]][Y0] - spec[idx[i]-1][Y1]) + spec[idx[i]-1][Y1];
+                       
+                       lut[i] = clip(v);
+               }
+               
+               lut[n-1] = clip(spec[spec.length-1][Y0]);
+               
+               return lut;
+       }
+
+       private static final float clip(float v) {
+               return (v < 0) ? 0 : (v > 1 ? 1 : v);
+       }
+}
diff --git a/Annotation/src/ie/dcu/image/dt/DistanceTransform.class b/Annotation/src/ie/dcu/image/dt/DistanceTransform.class
new file mode 100644 (file)
index 0000000..cc4f5b1
Binary files /dev/null and b/Annotation/src/ie/dcu/image/dt/DistanceTransform.class differ
diff --git a/Annotation/src/ie/dcu/image/dt/DistanceTransform.java b/Annotation/src/ie/dcu/image/dt/DistanceTransform.java
new file mode 100644 (file)
index 0000000..0af6893
--- /dev/null
@@ -0,0 +1,416 @@
+package ie.dcu.image.dt;
+
+import ie.dcu.matrix.*;
+
+
+/**
+ * Compute distance transforms using Meijster's algorithm:
+ * 
+ * For details on the algorithm see:
+ * 
+ * <pre>
+ *    A General Algorithm for Computing Distance Transforms in Linear Time.
+ *    Meijster et al. Computational Imaging and Vision (2000)
+ * </pre>
+ * 
+ * Meijster's algorithm appears to be the most efficient exact Euclidean 
+ * distance transform algorithm in most situations. For more details see:
+ * 
+ * <pre>
+ *    2D Euclidean distance transform algorithms: A comparative survey. 
+ *    Fabbri et al. ACM Computing Surveys (2008) vol. 40 (1) pp. 1-44
+ * </pre>
+ * 
+ * <b>Note:</b> If the matrix given for transform contains no background
+ * pixels, then each pixel will have a value of Integer.MAX_VALUE - rows**2 
+ * -cols**2
+ * 
+ * 
+ * @author Kevin McGuinness
+ */
+public class DistanceTransform {
+       private IntMatrix matrix;
+       private int inf;
+       private boolean done;
+       
+       /**
+        * Create distance transform object
+        */
+       public DistanceTransform() {
+               done = false;
+       }
+       
+       /**
+        * Returns true if the computation has been done.
+        */
+       public boolean isComputed() {
+               return done;
+       }
+       
+       /**
+        * Returns true if the transform has been initialized.
+        */
+       public boolean isInitialized() {
+               return matrix != null;
+       }
+       
+       
+       /**
+        * Private initializer
+        */
+       private void init(Matrix m) {
+               this.matrix = new IntMatrix(m.rows, m.cols);
+               this.inf = Integer.MAX_VALUE - m.rows * m.rows - m.cols * m.cols;
+               this.done = false;
+       }
+       
+       /**
+        * Private routine to check if the transform is possible.
+        */
+       private boolean isTransformPossible() {
+               // Cannot be called when done
+               assert (!done);
+               
+               for (int i = 0; i < matrix.size; i++) {
+                       if (matrix.values[i] == 0) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+       
+       /**
+        * Initialize transform with an integer matrix.
+        * 
+        * @param m
+        *        An integer matrix
+        * @param foregroundValue
+        *        The value of a foreground pixel
+        * @return 
+        *        true if the transform is possible
+        */
+       public boolean init(IntMatrix m, int foregroundValue) {
+               init(m);
+               
+               for (int i = 0; i < m.size; i++) {
+                       matrix.values[i] = m.values[i] == foregroundValue ? inf : 0;
+               }
+               
+               return isTransformPossible();
+       }
+       
+       /**
+        * Initialize transform with an short matrix.
+        * 
+        * @param m
+        *        An short matrix
+        * @param foregroundValue
+        *        The value of a foreground pixel
+        * @return 
+        *        true if the transform is possible
+        */
+       public boolean init(ShortMatrix m, short foregroundValue) {
+               init(m);
+               
+               for (int i = 0; i < m.size; i++) {
+                       matrix.values[i] = m.values[i] == foregroundValue ? inf : 0;
+               }
+               
+               return isTransformPossible();
+       }
+       
+       /**
+        * Initialize transform with an byte matrix.
+        * 
+        * @param m
+        *        An byte matrix
+        * @param foregroundValue
+        *        The value of a foreground pixel
+        * @return 
+        *        true if the transform is possible
+        */
+       public boolean init(ByteMatrix m, byte foregroundValue) {
+               init(m);
+               
+               for (int i = 0; i < m.size; i++) {
+                       matrix.values[i] = m.values[i] == foregroundValue ? inf : 0;
+               }
+               
+               return isTransformPossible();
+       }
+       
+       /**
+        * Initialize transform with an long matrix.
+        * 
+        * @param m
+        *        An long matrix
+        * @param foregroundValue
+        *        The value of a foreground pixel
+        * @return 
+        *        true if the transform is possible
+        */
+       public boolean init(LongMatrix m, long foregroundValue) {
+               init(m);
+               
+               for (int i = 0; i < m.size; i++) {
+                       matrix.values[i] = m.values[i] == foregroundValue ? inf : 0;
+               }
+               
+               return isTransformPossible();
+       }
+       
+       /**
+        * Initialize transform with an double matrix.
+        * 
+        * @param m
+        *        An double matrix
+        * @param foregroundValue
+        *        The value of a foreground pixel
+        * @return 
+        *        true if the transform is possible
+        */
+       public boolean init(DoubleMatrix m, double foregroundValue) {
+               init(m);
+               
+               for (int i = 0; i < m.size; i++) {
+                       matrix.values[i] = m.values[i] == foregroundValue ? inf : 0;
+               }
+               
+               return isTransformPossible();
+       }
+       
+       /**
+        * Initialize transform with an float matrix.
+        * 
+        * @param m
+        *        An float matrix
+        * @param foregroundValue
+        *        The value of a foreground pixel
+        * @return 
+        *        true if the transform is possible
+        */
+       public boolean init(FloatMatrix m, float foregroundValue) {
+               init(m);
+               
+               for (int i = 0; i < m.size; i++) {
+                       matrix.values[i] = m.values[i] == foregroundValue ? inf : 0;
+               }
+               
+               return isTransformPossible();
+       }
+       
+       /**
+        * Initialize transform with an arbitrary matrix.
+        * 
+        * @param m
+        *        A matrix
+        * @param foregroundValue
+        *        The value of a foreground pixel
+        * @return 
+        *        true if the transform is possible
+        */
+       public boolean init(Matrix m, Number foregroundValue) {
+               init(m);
+               
+               double fgv = foregroundValue.doubleValue();
+               for (int i = 0; i < m.size; i++) {
+                       
+                       matrix.values[i] = m.valueAt(i).doubleValue() == fgv ? inf : 0;
+               }
+               
+               return isTransformPossible();
+       }
+       
+       /**
+        * Performs the column transform
+        */
+       private final void transformCols() {
+                               
+               for (int j = 0; j < matrix.cols; j++) {
+
+                       // Forward
+                       for (int i = 1, b = 1; i < matrix.rows; i++) {
+                               int idx = i * matrix.cols + j;
+                               
+                               if (matrix.values[idx] > matrix.values[idx-matrix.cols]) {
+                                       matrix.values[idx] = matrix.values[idx-matrix.cols] + b;
+                                       b += 2;
+                               } else {
+                                       b = 1;
+                               }
+                       }
+                       
+                       // Backward
+                       for (int i = matrix.rows - 2, b = 1; i >= 0; i--) {
+                               int idx = i * matrix.cols + j;
+                               
+                               if (matrix.values[idx] > matrix.values[idx+matrix.cols] + b) {
+                                       matrix.values[idx] = matrix.values[idx+matrix.cols] + b;
+                                       b += 2;
+                               } else {
+                                       b = 1;
+                               }
+                       }
+               }
+       }
+       
+       /**
+        * Meijsters f function
+        */
+       private static int f(int x, int i, int pixel) {
+               return (x - i)*(x - i) + pixel;
+       }
+       
+       /**
+        * Performs the row transform
+        */
+       private final void transformRows() {
+               // Meijster row transform
+               
+               int[] s = new int[matrix.cols];
+               int[] t = new int[matrix.cols];
+               int[] r = new int[matrix.cols];
+               
+               for (int i = 0; i < matrix.rows; i++) {
+                       int q = s[0] = t[0] = 0;
+                       int offset = i * matrix.cols;
+                       
+                       for (int u = 1; u < matrix.cols; ++u) {
+                               int im_r_u = matrix.values[offset + u];
+                               
+                               while (q != -1 && 
+                                       f(t[q], s[q], matrix.values[offset + s[q]]) > 
+                                       f(t[q], u, im_r_u)) {
+                                       --q;
+                               }
+                               
+                               if (q == -1) {
+                                       q = 0;
+                                       s[0] = u;
+                               } else {
+                                       int w = 1 + ((u * u - (s[q] * s[q]) + 
+                                                       matrix.values[offset + u] - matrix.values[offset + s[q]]) 
+                                                       / (2 * (u - s[q])));
+                                       if (w < matrix.cols) {
+                                               ++q;
+                                               s[q] = u;
+                                               t[q] = w;
+                                       }
+                               }
+                       }
+                       
+                       System.arraycopy(matrix.values, offset, r, 0, matrix.cols);
+
+                   for (int u = matrix.cols - 1; u != -1; --u) {
+                       matrix.values[offset + u] = f(u, s[q], r[s[q]]);
+
+                               if (u == t[q]) {
+                                       --q;
+                               }
+                       }
+               }
+       }
+       
+       /**
+        * Carries out the transform if it has not already been completed
+        */
+       private void squareTransform() {
+               if (matrix == null) {
+                       throw new IllegalStateException("transform object not initialized");
+               }
+               
+               if (!done) {
+                       if (matrix.rows > 0 && matrix.cols > 0) {
+                               transformCols();
+                               transformRows();
+                       }
+                       done = true;
+               }
+       }
+       
+       /**
+        * Compute the square euclidean distance transform and return the result as
+        * a flattened integer array of square distance values, that has a size of 
+        * rows * columns.
+        * 
+        * @return flat array of square distance values.
+        */
+       public IntMatrix computeSquareTransform() {
+               squareTransform();
+               return matrix.clone();
+       }
+       
+       /**
+        * Compute the euclidean distance transform and return the result as a 
+        * flattened array of double precision floating point values. The returned
+        * array has a dimension of rows * columns.
+        * 
+        * @return flattened array of euclidean distance values.
+        */
+       public DoubleMatrix computeTransform() {
+               squareTransform();
+               
+               DoubleMatrix result = new DoubleMatrix(matrix.rows, matrix.cols);
+               for (int i = 0; i < matrix.size; i++) {
+                       result.values[i] = Math.sqrt(matrix.values[i]);
+               }
+               
+               return result;
+       }
+       
+       /**
+        * Compute the euclidean distance transform and return the result as a 
+        * flattened array of single precision floating point values. The returned
+        * array has a dimension of rows * columns.
+        * 
+        * @return flattened array of euclidean distance values.
+        */
+       public FloatMatrix computeTransformFloat() {
+               squareTransform();
+               
+               FloatMatrix result = new FloatMatrix(matrix.rows, matrix.cols);
+               for (int i = 0; i < matrix.size; i++) {
+                       result.values[i] = (float) Math.sqrt(matrix.values[i]);
+               }
+               
+               return result;
+       }
+       
+       // Some test code
+       public static void main(String[] args) {
+               
+               // Create rectangular mask
+               int[][] pixels = new int[11][11];
+               for (int i = 0; i < pixels.length; i++) {
+                       for (int j = 0; j < pixels[i].length; j++) {
+                               pixels[i][j] = 0;
+                       }
+               }
+               pixels[5][5] = 1;
+               
+               // Print mask
+               System.out.println("Pixels: ");
+               for (int i = 0; i < pixels.length; i++) {
+                       for (int j = 0; j < pixels[i].length; j++) {
+                               System.out.printf("%3d", pixels[i][j]);
+                               System.out.print(' ');
+                       }
+                       System.out.println();
+               }
+               
+               // Transform
+               DistanceTransform dt = new DistanceTransform();
+               dt.init(new IntMatrix(pixels), 0);
+               DoubleMatrix result = dt.computeTransform();
+               
+               // Print transform
+               System.out.println("Result: ");
+               for (int i = 0; i < result.rows; i++) {
+                       for (int j = 0; j < result.cols; j++) {
+                               System.out.printf("%4.2f", result.doubleAt(i, j));
+                               System.out.print(' ');
+                       }
+                       System.out.println();
+               }
+       }
+}
diff --git a/Annotation/src/ie/dcu/image/gray/GrayConvolve.class b/Annotation/src/ie/dcu/image/gray/GrayConvolve.class
new file mode 100644 (file)
index 0000000..961d5eb
Binary files /dev/null and b/Annotation/src/ie/dcu/image/gray/GrayConvolve.class differ
diff --git a/Annotation/src/ie/dcu/image/gray/GrayConvolve.java b/Annotation/src/ie/dcu/image/gray/GrayConvolve.java
new file mode 100644 (file)
index 0000000..fa1c418
--- /dev/null
@@ -0,0 +1,37 @@
+package ie.dcu.image.gray;
+
+import ie.dcu.matrix.DoubleMatrix;
+
+public class GrayConvolve {
+
+       public static DoubleMatrix convolve(
+                       DoubleMatrix image, DoubleMatrix filter) 
+       {
+               DoubleMatrix result = new DoubleMatrix(image.rows, image.cols);
+               
+               for (int i = 0; i < image.rows; i++) {
+                       for (int j = 0; j < image.cols; j++) {
+                               double value  = 0.0;
+                               
+                               for (int ii = 0; ii < filter.rows; ii++) {
+                                       int i1 = i - (filter.rows >> 1) + ii;
+                                       
+                                       if (image.hasRow(i1)) {
+                                               for (int jj = 0; jj < filter.cols; jj++) {
+                                                       int j1 = j - (filter.cols >> 1) + jj;
+                                                       
+                                                       if (image.hasCol(j1)) {
+                                                               double filterValue = filter.doubleAt(ii, jj);
+                                                               value += image.doubleAt(i1, j1) * filterValue;
+                                                       }
+                                               }
+                                       }
+                               }
+                               
+                               result.setDoubleAt(i, j, value);
+                       }
+               }
+               
+               return result;
+       }
+}
diff --git a/Annotation/src/ie/dcu/image/gray/GrayImageOp.class b/Annotation/src/ie/dcu/image/gray/GrayImageOp.class
new file mode 100644 (file)
index 0000000..c134c67
Binary files /dev/null and b/Annotation/src/ie/dcu/image/gray/GrayImageOp.class differ
diff --git a/Annotation/src/ie/dcu/image/gray/GrayImageOp.java b/Annotation/src/ie/dcu/image/gray/GrayImageOp.java
new file mode 100644 (file)
index 0000000..86cf4c5
--- /dev/null
@@ -0,0 +1,8 @@
+package ie.dcu.image.gray;
+
+import ie.dcu.image.ImageOp;
+
+public interface GrayImageOp extends ImageOp {
+
+       
+}
diff --git a/Annotation/src/ie/dcu/image/gray/LaplaceFilterOp.class b/Annotation/src/ie/dcu/image/gray/LaplaceFilterOp.class
new file mode 100644 (file)
index 0000000..3835e87
Binary files /dev/null and b/Annotation/src/ie/dcu/image/gray/LaplaceFilterOp.class differ
diff --git a/Annotation/src/ie/dcu/image/gray/LaplaceFilterOp.java b/Annotation/src/ie/dcu/image/gray/LaplaceFilterOp.java
new file mode 100644 (file)
index 0000000..ff1791a
--- /dev/null
@@ -0,0 +1,125 @@
+package ie.dcu.image.gray;
+
+import ie.dcu.image.AbstractImageOp;
+import ie.dcu.matrix.*;
+import ie.dcu.matrix.Matrix.Type;
+
+public class LaplaceFilterOp extends AbstractImageOp 
+       implements GrayImageOp 
+{
+       
+       private boolean clampOutput = true;
+       private boolean simple = false;
+       
+       public static DoubleMatrix rectify(ByteMatrix bm) {
+               DoubleMatrix im = new DoubleMatrix(bm.rows, bm.cols);
+               for (int i = 0; i < bm.size; i++) {
+                       im.values[i] = (int) bm.values[i] - (int) Byte.MIN_VALUE;
+               }
+               return im;
+       }
+
+       @Override
+       protected Matrix processImage(MatrixProvider provider) {
+               Type type = provider.getDefaultMatrixType();
+               
+               DoubleMatrix input;
+               if (type != null && type == Type.Byte) {
+                       ByteMatrix matrix = (ByteMatrix) provider.getMatrix(Type.Byte, false);
+                       input = rectify(matrix);
+               } else {
+                       input = (DoubleMatrix) provider.getMatrix(Type.Double, false);
+               }
+               
+               DoubleMatrix output = simple ? laplace4(input) : laplace8(input);
+               
+               
+               System.out.println("input min = " + input.minValue());
+               System.out.println("input max = " + input.maxValue());
+               System.out.println("output min = " + output.minValue());
+               System.out.println("output max = " + output.maxValue());
+               
+               if (clampOutput) {
+                       
+                       output.clamp(0, Double.MAX_VALUE);
+               }
+               
+               return output;
+       }
+       
+       
+       public static DoubleMatrix laplace4(DoubleMatrix m) {
+               DoubleMatrix result = new DoubleMatrix(m.rows, m.cols);
+               
+               double n0, n1, n2, n3;
+               for (int i = 0; i < m.rows; i++) {
+                       
+                       n0 = (i != 0) ? 1 : 0;
+                       n3 = (i != m.rows - 1) ? 1 : 0;
+                       
+                       for (int j = 0; j < m.cols; j++) {
+                               
+                                n1 = (j != 0) ? 1 : 0;
+                                n2 = (j != m.cols-1) ? 1 : 0;
+                                
+                                double value = (n0 + n1 + n2 + n3) * m.doubleAt(i, j);
+                                value -= (n0 != 0) ? m.doubleAt(i-1, j) : 0;
+                                value -= (n1 != 0) ? m.doubleAt(i, j-1) : 0;
+                                value -= (n2 != 0) ? m.doubleAt(i, j+1) : 0;
+                                value -= (n3 != 0) ? m.doubleAt(i+1, j) : 0;
+                                result.setDoubleAt(i, j, value);
+                       }
+               }
+               
+               return result;
+       }
+
+       public static DoubleMatrix laplace8(DoubleMatrix m) {
+               DoubleMatrix result = new DoubleMatrix(m.rows, m.cols);
+               
+               int a = m.rows - 1;
+               int b = m.cols - 1;
+               
+               double n0, n1, n2, n3, n4, n5, n6, n7;
+               for (int i = 0; i < m.rows; i++) {
+                       
+                       for (int j = 0; j < m.cols; j++) {
+                               
+                               n0 = (i != 0 && j != 0) ? 1 : 0;
+                               n1 = (i != 0) ? 1 : 0;
+                               n2 = (i != 0 && j != b) ? 1 : 0;
+                               n3 = (j != 0) ? 1 : 0;
+                               n4 = (j != b) ? 1 : 0;
+                               n5 = (i != a && j != 0) ? 1 : 0;
+                               n6 = (i != a) ? 1 : 0;
+                               n7 = (i != a && j != b) ? 1 : 0;
+                               
+                               double w = (n0 + n1 + n2 + n3 + n4 + n5 + n6 + n7);
+                               double v = w * m.doubleAt(i, j);
+                               
+                               v -= (n0 != 0) ? m.doubleAt(i-1, j-1) : 0;
+                               v -= (n1 != 0) ? m.doubleAt(i-1, j  ) : 0;
+                               v -= (n2 != 0) ? m.doubleAt(i-1, j+1) : 0;
+                               v -= (n3 != 0) ? m.doubleAt(i  , j-1) : 0;
+                               v -= (n4 != 0) ? m.doubleAt(i  , j+1) : 0;
+                               v -= (n5 != 0) ? m.doubleAt(i+1, j-1) : 0;
+                               v -= (n6 != 0) ? m.doubleAt(i+1, j  ) : 0;
+                               v -= (n7 != 0) ? m.doubleAt(i+1, j+1) : 0;
+                               
+                               result.setDoubleAt(i, j, v);
+                       }
+               }
+               
+               return result;
+       }
+       
+       /*
+        * (non-Javadoc)
+        * @see ie.dcu.cdvp.matrix.MatrixProvider#getDefaultMatrixType()
+        */
+       public Type getDefaultMatrixType() {
+               // we don't know
+               return null;
+       }
+       
+}
diff --git a/Annotation/src/ie/dcu/matrix/ByteMatrix.class b/Annotation/src/ie/dcu/matrix/ByteMatrix.class
new file mode 100644 (file)
index 0000000..78909dd
Binary files /dev/null and b/Annotation/src/ie/dcu/matrix/ByteMatrix.class differ
diff --git a/Annotation/src/ie/dcu/matrix/ByteMatrix.java b/Annotation/src/ie/dcu/matrix/ByteMatrix.java
new file mode 100644 (file)
index 0000000..885d24a
--- /dev/null
@@ -0,0 +1,431 @@
+/*
+ * ByteMatrix.java
+ *
+ * Copyright (c) 2009 by Kevin McGuinness 
+ */
+package ie.dcu.matrix;
+
+import ie.dcu.array.Arrays;
+
+/**
+ * Two dimensional matrix of byte values.
+ *
+ * @author Kevin McGuinness
+ */
+public class ByteMatrix extends Matrix {
+    
+    /**
+     * Serialization UID.
+     */
+       private static final long serialVersionUID = 6250820249861612603L;
+       
+       /**
+        * Shared empty matrix 
+        */
+       private static final ByteMatrix EMPTY_MATRIX = new ByteMatrix(0,0);
+       
+       /**
+        * The byte values of the matrix in row-major order.
+        */
+       public final byte[] values;
+
+    /**
+     * Construct an uninitialized matrix of the given size.
+     *
+     * @param rows
+     *        The number of rows
+     * @param cols
+     *        The number of columns
+     */
+       public ByteMatrix(int rows, int cols) {
+               super(Type.Byte, rows, cols);
+               values = new byte[size];
+       }
+       
+       /**
+        * Construct a matrix of the given size with the given values.
+        * 
+        * @param rows
+     *        The number of rows
+     * @param cols
+     *        The number of columns
+        * @param values
+        *        The values to the matrix will have (not copied).
+        */
+       public ByteMatrix(int rows, int cols, byte ... values) {                
+               super(Type.Byte, rows, cols, values.length);
+               this.values = values;
+       }
+       
+       /**
+        * Construct a matrix of the given size by copying the values in the 
+        * given two dimensional array.
+        * 
+        * The passed two dimensional array must consist of arrays that have
+        * the same dimension.
+        * 
+        * @param matrix
+        *        A two dimensional array of byte values.
+        * @throws IllegalArgumentException
+        *        If the matrix does not contain arrays of the same dimension.       
+        */
+       public ByteMatrix(byte[][] matrix) {
+               this(rowsIn(matrix), colsIn(matrix));
+               flatten(matrix, values);
+       }
+       
+       /**
+        * Returns the byte value at the given row and column index.
+        *
+        * @param row
+        *        The row index.
+        * @param col
+        *        The column index.
+        * @return 
+        *        The byte value at (row, col).
+        */
+       public final byte byteAt(int row, int col) {
+               return values[offsetOf(row, col)];
+       }
+       
+    /**
+        * Returns the byte value at the index.
+        *
+        * @param index
+        *        The index
+        * @return 
+        *        The byte value
+        */
+       public final byte byteAt(Index2D index) {
+               return values[offsetOf(index)];
+       }
+
+    /**
+        * Set the byte value at the given row and column index.
+        *
+        * @param row
+        *        The row index.
+        * @param col
+        *        The column index.
+        * @param value 
+        *        The byte value to set.
+        */
+       public final void setByteAt(int row, int col, byte value) {
+               values[offsetOf(row, col)] = value;
+       }
+       
+       /**
+        * Set the byte value at the given index.
+        *
+        * @param index
+        *        The index.
+        * @param value 
+        *        The byte value to set.
+        */
+       public final void setByteAt(Index2D index, byte value) {
+               values[offsetOf(index)] = value;
+       }
+       
+       /**
+        * Returns the byte value at the given offset in the matrix.
+        *
+        * @param offset
+        *        The absolute offset in the matrix.
+        * @return 
+        *        The byte value at the given offset.
+        */
+       public final byte byteAt(int offset) {
+               return values[offset];
+       }
+
+    /**
+        * Set the byte value at the given offset in the matrix.
+        *
+        * @param offset
+        *        The matrix offset
+        * @param value 
+        *        The byte value to set.
+        */
+       public final void setByteAt(int offset, byte value) {
+               values[offset] = value;
+       }
+       
+       /**
+        * Returns the smallest byte value in the matrix.
+        *
+        * @return
+        *        The smallest byte value, or <code>null</code> if the 
+        *        matrix is empty.
+        */
+       public final Byte minValue() {
+           return Arrays.min(values);
+       }
+       
+       /**
+        * Returns the largest byte value in the matrix.
+        *
+        * @return
+        *        The largest byte value, or <code>null</code> if the 
+        *        matrix is empty.
+        */
+       public final Byte maxValue() {
+               return Arrays.max(values);
+       }
+       
+       /**
+        * Returns a transposed version of the matrix.
+        */
+       public final ByteMatrix transpose() {
+               ByteMatrix m = new ByteMatrix(cols, rows);
+               for (int i = 0; i < rows; i++) {
+                       for (int j = 0; j < cols; j++) {
+                               m.values[offsetOf(j,i)] = values[offsetOf(i, j)];
+                       }
+               }
+               return m;
+       }
+
+    /**
+     * Returns a deep copy of the matrix.
+     */
+       @Override
+       public ByteMatrix clone() {
+               return new ByteMatrix(rows, cols, values.clone());
+       }
+
+    /**
+     * Returns true if both matrices are equal in value.
+     */
+       @Override
+       public boolean equals(Object obj) {
+               if (obj instanceof ByteMatrix) {
+                       ByteMatrix m = (ByteMatrix) obj;
+                       if (sizeEquals(m)) {
+                               return java.util.Arrays.equals(values, m.values);
+                       }
+                       return false;
+               }
+               return super.equals(obj);               
+       }
+
+    /**
+     * Fills the matrix with the %{primative} value of the given number.
+     *
+     * @param number
+     *        The number to fill the matrix with (will be truncated if 
+     *        necessary).
+     * @return 
+     *        This matrix.
+     */
+       @Override
+       public final ByteMatrix fill(Number number) {
+               java.util.Arrays.fill(values, number.byteValue());
+               return this;
+       }
+
+    /**
+     * Returns the Byte value at the given row and column index.
+     *
+     * @param row
+        *        The row index.
+        * @param col
+        *        The column index.
+        * @return 
+        *        The Byte value at (row, col).
+     */
+       @Override
+       public final Byte valueAt(int row, int col) {
+               return values[offsetOf(row, col)];
+       }
+       
+       /**
+        * Set the Number value at the given row and column index.
+        *
+        * @param row
+        *        The row index.
+        * @param col
+        *        The column index.
+        * @param value 
+        *        The Number value to set (will be truncated if necessary).
+        */
+       @Override
+       public final void setValueAt(int row, int col, Number value) {
+               values[offsetOf(row, col)] = value.byteValue();
+       }
+       
+       /**
+     * Returns the Byte value at the given matrix offset.
+     *
+     * @param offset
+     *        The absolute offset in the matrix.
+        * @return 
+        *        The Byte value at the given offset.
+     */
+       @Override
+       public final Byte valueAt(int offset) {
+               return values[offset];
+       }
+       
+       /**
+        * Set the Number value at the given matrix offset.
+        *
+        * @param offset
+        *        The absolute offset in the matrix.
+        * @param value 
+        *        The Number value to set (will be truncated if necessary).
+        */
+       @Override
+       public final void setValueAt(int offset, Number value) {
+               values[offset] = value.byteValue();
+       }
+       
+       /**
+        * Returns the matrix values (not copied).
+        */
+       @Override
+       public final byte[] values() {
+               return values;
+       }
+       
+       /**
+        * Returns a shared empty matrix instance.
+        */
+       public static ByteMatrix empty() {
+               return EMPTY_MATRIX;
+       }
+       
+       /**
+        * Construct and return an identity matrix with the given number of rows.
+        *
+        * @param rows
+        *        The number of rows/columns for the matrix to have.
+        * @return
+        *        A new identity matrix.
+        */
+       public static ByteMatrix eye(int rows) {
+               ByteMatrix m = new ByteMatrix(rows, rows);
+               m.fill(0);
+               for (int i = 0; i < rows; i++) {
+                       m.setByteAt(i, i, (byte) 1);
+               }
+               return m;
+       }
+       
+       /**
+        * Construct and return an zero matrix with the given number of rows
+        * and columns.
+        *
+        * @param rows
+        *        The number of rows for the matrix to have.
+        * @param cols
+        *        The number of cols for the matrix to have.
+        * @return
+        *        A new zero matrix.
+        */
+       public static ByteMatrix zeros(int rows, int cols) {
+               ByteMatrix m = new ByteMatrix(rows, rows);
+               m.fill(0);
+               return m;
+       }
+       
+       /**
+        * Construct and return a matrix of ones with the given number of rows
+        * and columns.
+        *
+        * @param rows
+        *        The number of rows for the matrix to have.
+        * @param cols
+        *        The number of cols for the matrix to have.
+        * @return
+        *        A new matrix of ones.
+        */
+       public static ByteMatrix ones(int rows, int cols) {
+               ByteMatrix m = new ByteMatrix(rows, rows);
+               m.fill(1);
+               return m;
+       }
+       
+       /**
+     * Copy the given two dimensional array of byte values into the given 
+        * array. If the passed array does not contain at enough room for the
+        * passed matrix, a new array is allocated and returned.
+        * 
+        * The passed two dimensional array must consist of arrays that have
+        * the same dimension.
+        *
+        * The copy is performed such that the flattened array is in row major
+        * order. 
+        * 
+        * @param matrix
+        *        The 2D array of byte values to flatten
+        * @param array
+        *        The array to copy to (can be <code>null</code>).
+        * @return
+        *        A flattened version of the matrix.
+        * @throws IllegalArgumentException
+        *        If the matrix does not contain arrays of the same dimension.
+        */
+       public static final byte[] flatten(byte[][] matrix, byte[] array) {
+               int rows = matrix.length;
+               int cols = matrix.length > 0 ? matrix[0].length : 0;
+               int size = rows * cols;
+
+               if (array == null || array.length < size) { 
+                       array = new byte[size];
+               }
+
+               for (int i = 0; i < rows; i++) {
+
+                       if (cols != matrix[i].length) {
+                               throw new IllegalArgumentException();
+                       }
+
+                       System.arraycopy(matrix[i], 0, array, cols * i, cols);
+               }
+
+               return array;
+       }
+       
+    /**
+     * Returns the number of rows in the given two dimensional array.
+        * 
+        * @param matrix
+        *        A two dimensional array.
+        * @return
+        *        The number of rows.
+        */
+       public static final int rowsIn(byte[][] matrix) {
+               return matrix.length;
+       }
+
+       /**
+        * Returns the number of columns in the given two dimensional array.
+        * 
+        * This method assumes that the arrays in the given matrix all have
+        * equal lengths.
+        * 
+        * @param matrix
+        *        A two dimensional array.
+        * @return
+        *        The number of columns.
+        */
+       public static final int colsIn(byte[][] matrix) {
+               return matrix.length > 0 ? matrix[0].length : 0;
+       }
+
+       /**
+        * Returns the total number of elements in the given two dimensional 
+        * array.
+        * 
+        * This method assumes that the arrays in the given matrix all have
+        * equal lengths.
+        * 
+        * @param matrix
+        *        A two dimensional array.
+        * @return
+        *        The total number of elements.
+        */
+       public static final int sizeOf(byte[][] matrix) {
+               return rowsIn(matrix) * colsIn(matrix);
+       }
+}
diff --git a/Annotation/src/ie/dcu/matrix/DoubleMatrix.class b/Annotation/src/ie/dcu/matrix/DoubleMatrix.class
new file mode 100644 (file)
index 0000000..b001b7a
Binary files /dev/null and b/Annotation/src/ie/dcu/matrix/DoubleMatrix.class differ
diff --git a/Annotation/src/ie/dcu/matrix/DoubleMatrix.java b/Annotation/src/ie/dcu/matrix/DoubleMatrix.java
new file mode 100644 (file)
index 0000000..099d550
--- /dev/null
@@ -0,0 +1,431 @@
+/*
+ * DoubleMatrix.java
+ *
+ * Copyright (c) 2009 by Kevin McGuinness 
+ */
+package ie.dcu.matrix;
+
+import ie.dcu.array.Arrays;
+
+/**
+ * Two dimensional matrix of double values.
+ *
+ * @author Kevin McGuinness
+ */
+public class DoubleMatrix extends Matrix {
+    
+    /**
+     * Serialization UID.
+     */
+       private static final long serialVersionUID = 3466326831906456667L;
+       
+       /**
+        * Shared empty matrix 
+        */
+       private static final DoubleMatrix EMPTY_MATRIX = new DoubleMatrix(0,0);
+       
+       /**
+        * The double values of the matrix in row-major order.
+        */
+       public final double[] values;
+
+    /**
+     * Construct an uninitialized matrix of the given size.
+     *
+     * @param rows
+     *        The number of rows
+     * @param cols
+     *        The number of columns
+     */
+       public DoubleMatrix(int rows, int cols) {
+               super(Type.Double, rows, cols);
+               values = new double[size];
+       }
+       
+       /**
+        * Construct a matrix of the given size with the given values.
+        * 
+        * @param rows
+     *        The number of rows
+     * @param cols
+     *        The number of columns
+        * @param values
+        *        The values to the matrix will have (not copied).
+        */
+       public DoubleMatrix(int rows, int cols, double ... values) {            
+               super(Type.Double, rows, cols, values.length);
+               this.values = values;
+       }
+       
+       /**
+        * Construct a matrix of the given size by copying the values in the 
+        * given two dimensional array.
+        * 
+        * The passed two dimensional array must consist of arrays that have
+        * the same dimension.
+        * 
+        * @param matrix
+        *        A two dimensional array of double values.
+        * @throws IllegalArgumentException
+        *        If the matrix does not contain arrays of the same dimension.       
+        */
+       public DoubleMatrix(double[][] matrix) {
+               this(rowsIn(matrix), colsIn(matrix));
+               flatten(matrix, values);
+       }
+       
+       /**
+        * Returns the double value at the given row and column index.
+        *
+        * @param row
+        *        The row index.
+        * @param col
+        *        The column index.
+        * @return 
+        *        The double value at (row, col).
+        */
+       public final double doubleAt(int row, int col) {
+               return values[offsetOf(row, col)];
+       }
+       
+    /**
+        * Returns the double value at the index.
+        *
+        * @param index
+        *        The index
+        * @return 
+        *        The double value
+        */
+       public final double doubleAt(Index2D index) {
+               return values[offsetOf(index)];
+       }
+
+    /**
+        * Set the double value at the given row and column index.
+        *
+        * @param row
+        *        The row index.
+        * @param col
+        *        The column index.
+        * @param value 
+        *        The double value to set.
+        */
+       public final void setDoubleAt(int row, int col, double value) {
+               values[offsetOf(row, col)] = value;
+       }
+       
+       /**
+        * Set the double value at the given index.
+        *
+        * @param index
+        *        The index.
+        * @param value 
+        *        The double value to set.
+        */
+       public final void setDoubleAt(Index2D index, double value) {
+               values[offsetOf(index)] = value;
+       }
+       
+       /**
+        * Returns the double value at the given offset in the matrix.
+        *
+        * @param offset
+        *        The absolute offset in the matrix.
+        * @return 
+        *        The double value at the given offset.
+        */
+       public final double doubleAt(int offset) {
+               return values[offset];
+       }
+
+    /**
+        * Set the double value at the given offset in the matrix.
+        *
+        * @param offset
+        *        The matrix offset
+        * @param value 
+        *        The double value to set.
+        */
+       public final void setDoubleAt(int offset, double value) {
+               values[offset] = value;
+       }
+       
+       /**
+        * Returns the smallest double value in the matrix.
+        *
+        * @return
+        *        The smallest double value, or <code>null</code> if the 
+        *        matrix is empty.
+        */
+       public final Double minValue() {
+           return Arrays.min(values);
+       }
+       
+       /**
+        * Returns the largest double value in the matrix.
+        *
+        * @return
+        *        The largest double value, or <code>null</code> if the 
+        *        matrix is empty.
+        */
+       public final Double maxValue() {
+               return Arrays.max(values);
+       }
+       
+       /**
+        * Returns a transposed version of the matrix.
+        */
+       public final DoubleMatrix transpose() {
+               DoubleMatrix m = new DoubleMatrix(cols, rows);
+               for (int i = 0; i < rows; i++) {
+                       for (int j = 0; j < cols; j++) {
+                               m.values[offsetOf(j,i)] = values[offsetOf(i, j)];
+                       }
+               }
+               return m;
+       }
+
+    /**
+     * Returns a deep copy of the matrix.
+     */
+       @Override
+       public DoubleMatrix clone() {
+               return new DoubleMatrix(rows, cols, values.clone());
+       }
+
+    /**
+     * Returns true if both matrices are equal in value.
+     */
+       @Override
+       public boolean equals(Object obj) {
+               if (obj instanceof DoubleMatrix) {
+                       DoubleMatrix m = (DoubleMatrix) obj;
+                       if (sizeEquals(m)) {
+                               return java.util.Arrays.equals(values, m.values);
+                       }
+                       return false;
+               }
+               return super.equals(obj);               
+       }
+
+    /**
+     * Fills the matrix with the %{primative} value of the given number.
+     *
+     * @param number
+     *        The number to fill the matrix with (will be truncated if 
+     *        necessary).
+     * @return 
+     *        This matrix.
+     */
+       @Override
+       public final DoubleMatrix fill(Number number) {
+               java.util.Arrays.fill(values, number.doubleValue());
+               return this;
+       }
+
+    /**
+     * Returns the Double value at the given row and column index.
+     *
+     * @param row
+        *        The row index.
+        * @param col
+        *        The column index.
+        * @return 
+        *        The Double value at (row, col).
+     */
+       @Override
+       public final Double valueAt(int row, int col) {
+               return values[offsetOf(row, col)];
+       }
+       
+       /**
+        * Set the Number value at the given row and column index.
+        *
+        * @param row
+        *        The row index.
+        * @param col
+        *        The column index.
+        * @param value 
+        *        The Number value to set (will be truncated if necessary).
+        */
+       @Override
+       public final void setValueAt(int row, int col, Number value) {
+               values[offsetOf(row, col)] = value.doubleValue();
+       }
+       
+       /**
+     * Returns the Double value at the given matrix offset.
+     *
+     * @param offset
+     *        The absolute offset in the matrix.
+        * @return 
+        *        The Double value at the given offset.
+     */
+       @Override
+       public final Double valueAt(int offset) {
+               return values[offset];
+       }
+       
+       /**
+        * Set the Number value at the given matrix offset.
+        *
+        * @param offset
+        *        The absolute offset in the matrix.
+        * @param value 
+        *        The Number value to set (will be truncated if necessary).
+        */
+       @Override
+       public final void setValueAt(int offset, Number value) {
+               values[offset] = value.doubleValue();
+       }
+       
+       /**
+        * Returns the matrix values (not copied).
+        */
+       @Override
+       public final double[] values() {
+               return values;
+       }
+       
+       /**
+        * Returns a shared empty matrix instance.
+        */
+       public static DoubleMatrix empty() {
+               return EMPTY_MATRIX;
+       }
+       
+       /**
+        * Construct and return an identity matrix with the given number of rows.
+        *
+        * @param rows
+        *        The number of rows/columns for the matrix to have.
+        * @return
+        *        A new identity matrix.
+        */
+       public static DoubleMatrix eye(int rows) {
+               DoubleMatrix m = new DoubleMatrix(rows, rows);
+               m.fill(0);
+               for (int i = 0; i < rows; i++) {
+                       m.setDoubleAt(i, i, (double) 1);
+               }
+               return m;
+       }
+       
+       /**
+        * Construct and return an zero matrix with the given number of rows
+        * and columns.
+        *
+        * @param rows
+        *        The number of rows for the matrix to have.
+        * @param cols
+        *        The number of cols for the matrix to have.
+        * @return
+        *        A new zero matrix.
+        */
+       public static DoubleMatrix zeros(int rows, int cols) {
+               DoubleMatrix m = new DoubleMatrix(rows, rows);
+               m.fill(0);
+               return m;
+       }
+       
+       /**
+        * Construct and return a matrix of ones with the given number of rows
+        * and columns.
+        *
+        * @param rows
+        *        The number of rows for the matrix to have.
+        * @param cols
+        *        The number of cols for the matrix to have.
+        * @return
+        *        A new matrix of ones.
+        */
+       public static DoubleMatrix ones(int rows, int cols) {
+               DoubleMatrix m = new DoubleMatrix(rows, rows);
+               m.fill(1);
+               return m;
+       }
+       
+       /**
+     * Copy the given two dimensional array of double values into the given 
+        * array. If the passed array does not contain at enough room for the
+        * passed matrix, a new array is allocated and returned.
+        * 
+        * The passed two dimensional array must consist of arrays that have
+        * the same dimension.
+        *
+        * The copy is performed such that the flattened array is in row major
+        * order. 
+        * 
+        * @param matrix
+        *        The 2D array of double values to flatten
+        * @param array
+        *        The array to copy to (can be <code>null</code>).
+        * @return
+        *        A flattened version of the matrix.
+        * @throws IllegalArgumentException
+        *        If the matrix does not contain arrays of the same dimension.
+        */
+       public static final double[] flatten(double[][] matrix, double[] array) {
+               int rows = matrix.length;
+               int cols = matrix.length > 0 ? matrix[0].length : 0;
+               int size = rows * cols;
+
+               if (array == null || array.length < size) { 
+                       array = new double[size];
+               }
+
+               for (int i = 0; i < rows; i++) {
+
+                       if (cols != matrix[i].length) {
+                               throw new IllegalArgumentException();
+                       }
+
+                       System.arraycopy(matrix[i], 0, array, cols * i, cols);
+               }
+
+               return array;
+       }
+       
+    /**
+     * Returns the number of rows in the given two dimensional array.
+        * 
+        * @param matrix
+        *        A two dimensional array.
+        * @return
+        *        The number of rows.
+        */
+       public static final int rowsIn(double[][] matrix) {
+               return matrix.length;
+       }
+
+       /**
+        * Returns the number of columns in the given two dimensional array.
+        * 
+        * This method assumes that the arrays in the given matrix all have
+        * equal lengths.
+        * 
+        * @param matrix
+        *        A two dimensional array.
+        * @return
+        *        The number of columns.
+        */
+       public static final int colsIn(double[][] matrix) {
+               return matrix.length > 0 ? matrix[0].length : 0;
+       }
+
+       /**
+        * Returns the total number of elements in the given two dimensional 
+        * array.
+        * 
+        * This method assumes that the arrays in the given matrix all have
+        * equal lengths.
+        * 
+        * @param matrix
+        *        A two dimensional array.
+        * @return
+        *        The total number of elements.
+        */
+       public static final int sizeOf(double[][] matrix) {
+               return rowsIn(matrix) * colsIn(matrix);
+       }
+}
diff --git a/Annotation/src/ie/dcu/matrix/FloatMatrix.class b/Annotation/src/ie/dcu/matrix/FloatMatrix.class
new file mode 100644 (file)
index 0000000..822fbf4
Binary files /dev/null and b/Annotation/src/ie/dcu/matrix/FloatMatrix.class differ
diff --git a/Annotation/src/ie/dcu/matrix/FloatMatrix.java b/Annotation/src/ie/dcu/matrix/FloatMatrix.java
new file mode 100644 (file)
index 0000000..ad4f6ba
--- /dev/null
@@ -0,0 +1,431 @@
+/*
+ * FloatMatrix.java
+ *
+ * Copyright (c) 2009 by Kevin McGuinness 
+ */
+package ie.dcu.matrix;
+
+import ie.dcu.array.Arrays;
+
+/**
+ * Two dimensional matrix of float values.
+ *
+ * @author Kevin McGuinness
+ */
+public class FloatMatrix extends Matrix {
+    
+    /**
+     * Serialization UID.
+     */
+       private static final long serialVersionUID = 8664083529390696723L;
+       
+       /**
+        * Shared empty matrix 
+        */
+       private static final FloatMatrix EMPTY_MATRIX = new FloatMatrix(0,0);
+       
+       /**
+        * The float values of the matrix in row-major order.
+        */
+       public final float[] values;
+
+    /**
+     * Construct an uninitialized matrix of the given size.
+     *
+     * @param rows
+     *        The number of rows
+     * @param cols
+     *        The number of columns
+     */
+       public FloatMatrix(int rows, int cols) {
+               super(Type.Float, rows, cols);
+               values = new float[size];
+       }
+       
+       /**
+        * Construct a matrix of the given size with the given values.
+        * 
+        * @param rows
+     *        The number of rows
+     * @param cols
+     *        The number of columns
+        * @param values
+        *        The values to the matrix will have (not copied).
+        */
+       public FloatMatrix(int rows, int cols, float ... values) {              
+               super(Type.Float, rows, cols, values.length);
+               this.values = values;
+       }
+       
+       /**
+        * Construct a matrix of the given size by copying the values in the 
+        * given two dimensional array.
+        * 
+        * The passed two dimensional array must consist of arrays that have
+        * the same dimension.
+        * 
+        * @param matrix
+        *        A two dimensional array of float values.
+        * @throws IllegalArgumentException
+        *        If the matrix does not contain arrays of the same dimension.       
+        */
+       public FloatMatrix(float[][] matrix) {
+               this(rowsIn(matrix), colsIn(matrix));
+               flatten(matrix, values);
+       }
+       
+       /**
+        * Returns the float value at the given row and column index.
+        *
+        * @param row
+        *        The row index.
+        * @param col
+        *        The column index.
+        * @return 
+        *        The float value at (row, col).
+        */
+       public final float floatAt(int row, int col) {
+               return values[offsetOf(row, col)];
+       }
+       
+    /**
+        * Returns the float value at the index.
+        *
+        * @param index
+        *        The index
+        * @return 
+        *        The float value
+        */
+       public final float floatAt(Index2D index) {
+               return values[offsetOf(index)];
+       }
+
+    /**
+        * Set the float value at the given row and column index.
+        *
+        * @param row
+        *        The row index.
+        * @param col
+        *        The column index.
+        * @param value 
+        *        The float value to set.
+        */
+       public final void setFloatAt(int row, int col, float value) {
+               values[offsetOf(row, col)] = value;
+       }
+       
+       /**
+        * Set the float value at the given index.
+        *
+        * @param index
+        *        The index.
+        * @param value 
+        *        The float value to set.
+        */
+       public final void setFloatAt(Index2D index, float value) {
+               values[offsetOf(index)] = value;
+       }
+       
+       /**
+        * Returns the float value at the given offset in the matrix.
+        *
+        * @param offset
+        *        The absolute offset in the matrix.
+        * @return 
+        *        The float value at the given offset.
+        */
+       public final float floatAt(int offset) {
+               return values[offset];
+       }
+
+    /**
+        * Set the float value at the given offset in the matrix.
+        *
+        * @param offset
+        *        The matrix offset
+        * @param value 
+        *        The float value to set.
+        */
+       public final void setFloatAt(int offset, float value) {
+               values[offset] = value;
+       }
+       
+       /**
+        * Returns the smallest float value in the matrix.
+        *
+        * @return
+        *        The smallest float value, or <code>null</code> if the 
+        *        matrix is empty.
+        */
+       public final Float minValue() {
+           return Arrays.min(values);
+       }
+       
+       /**
+        * Returns the largest float value in the matrix.
+        *
+        * @return
+        *        The largest float value, or <code>null</code> if the 
+        *        matrix is empty.
+        */
+       public final Float maxValue() {
+               return Arrays.max(values);
+       }
+       
+       /**
+        * Returns a transposed version of the matrix.
+        */
+       public final FloatMatrix transpose() {
+               FloatMatrix m = new FloatMatrix(cols, rows);
+               for (int i = 0; i < rows; i++) {
+                       for (int j = 0; j < cols; j++) {
+                               m.values[offsetOf(j,i)] = values[offsetOf(i, j)];
+                       }
+               }
+               return m;
+       }
+
+    /**
+     * Returns a deep copy of the matrix.
+     */
+       @Override
+       public FloatMatrix clone() {
+               return new FloatMatrix(rows, cols, values.clone());
+       }
+
+    /**
+     * Returns true if both matrices are equal in value.
+     */
+       @Override
+       public boolean equals(Object obj) {
+               if (obj instanceof FloatMatrix) {
+                       FloatMatrix m = (FloatMatrix) obj;
+                       if (sizeEquals(m)) {
+                               return java.util.Arrays.equals(values, m.values);
+                       }
+                       return false;
+               }
+               return super.equals(obj);               
+       }
+
+    /**
+     * Fills the matrix with the %{primative} value of the given number.
+     *
+     * @param number
+     *        The number to fill the matrix with (will be truncated if 
+     *        necessary).
+     * @return 
+     *        This matrix.
+     */
+       @Override
+       public final FloatMatrix fill(Number number) {
+               java.util.Arrays.fill(values, number.floatValue());
+               return this;
+       }
+
+    /**
+     * Returns the Float value at the given row and column index.
+     *
+     * @param row
+        *        The row index.
+        * @param col
+        *        The column index.
+        * @return 
+        *        The Float value at (row, col).
+     */
+       @Override
+       public final Float valueAt(int row, int col) {
+               return values[offsetOf(row, col)];
+       }
+       
+       /**
+        * Set the Number value at the given row and column index.
+        *
+        * @param row
+        *        The row index.
+        * @param col
+        *        The column index.
+        * @param value 
+        *        The Number value to set (will be truncated if necessary).
+        */
+       @Override
+       public final void setValueAt(int row, int col, Number value) {
+               values[offsetOf(row, col)] = value.floatValue();
+       }
+       
+       /**
+     * Returns the Float value at the given matrix offset.
+     *
+     * @param offset
+     *        The absolute offset in the matrix.
+        * @return 
+        *        The Float value at the given offset.
+     */
+       @Override
+       public final Float valueAt(int offset) {
+               return values[offset];
+       }
+       
+       /**
+        * Set the Number value at the given matrix offset.
+        *
+        * @param offset
+        *        The absolute offset in the matrix.
+        * @param value 
+        *        The Number value to set (will be truncated if necessary).
+        */
+       @Override
+       public final void setValueAt(int offset, Number value) {
+               values[offset] = value.floatValue();
+       }
+       
+       /**
+        * Returns the matrix values (not copied).
+        */
+       @Override
+       public final float[] values() {
+               return values;
+       }
+       
+       /**
+        * Returns a shared empty matrix instance.
+        */
+       public static FloatMatrix empty() {
+               return EMPTY_MATRIX;
+       }
+       
+       /**
+        * Construct and return an identity matrix with the given number of rows.
+        *
+        * @param rows
+        *        The number of rows/columns for the matrix to have.
+        * @return
+        *        A new identity matrix.
+        */
+       public static FloatMatrix eye(int rows) {
+               FloatMatrix m = new FloatMatrix(rows, rows);
+               m.fill(0);
+               for (int i = 0; i < rows; i++) {
+                       m.setFloatAt(i, i, (float) 1);
+               }
+               return m;
+       }
+       
+       /**
+        * Construct and return an zero matrix with the given number of rows
+        * and columns.
+        *
+        * @param rows
+        *        The number of rows for the matrix to have.
+        * @param cols
+        *        The number of cols for the matrix to have.
+        * @return
+        *        A new zero matrix.
+        */
+       public static FloatMatrix zeros(int rows, int cols) {
+               FloatMatrix m = new FloatMatrix(rows, rows);
+               m.fill(0);
+               return m;
+       }
+       
+       /**
+        * Construct and return a matrix of ones with the given number of rows
+        * and columns.
+        *
+        * @param rows
+        *        The number of rows for the matrix to have.
+        * @param cols
+        *        The number of cols for the matrix to have.
+        * @return
+        *        A new matrix of ones.
+        */
+       public static FloatMatrix ones(int rows, int cols) {
+               FloatMatrix m = new FloatMatrix(rows, rows);
+               m.fill(1);
+               return m;
+       }
+       
+       /**
+     * Copy the given two dimensional array of float values into the given 
+        * array. If the passed array does not contain at enough room for the
+        * passed matrix, a new array is allocated and returned.
+        * 
+        * The passed two dimensional array must consist of arrays that have
+        * the same dimension.
+        *
+        * The copy is performed such that the flattened array is in row major
+        * order. 
+        * 
+        * @param matrix
+        *        The 2D array of float values to flatten
+        * @param array
+        *        The array to copy to (can be <code>null</code>).
+        * @return
+        *        A flattened version of the matrix.
+        * @throws IllegalArgumentException
+        *        If the matrix does not contain arrays of the same dimension.
+        */
+       public static final float[] flatten(float[][] matrix, float[] array) {
+               int rows = matrix.length;
+               int cols = matrix.length > 0 ? matrix[0].length : 0;
+               int size = rows * cols;
+
+               if (array == null || array.length < size) { 
+                       array = new float[size];
+               }
+
+               for (int i = 0; i < rows; i++) {
+
+                       if (cols != matrix[i].length) {
+                               throw new IllegalArgumentException();
+                       }
+
+                       System.arraycopy(matrix[i], 0, array, cols * i, cols);
+               }
+
+               return array;
+       }
+       
+    /**
+     * Returns the number of rows in the given two dimensional array.
+        * 
+        * @param matrix
+        *        A two dimensional array.
+        * @return
+        *        The number of rows.
+        */
+       public static final int rowsIn(float[][] matrix) {
+               return matrix.length;
+       }
+
+       /**
+        * Returns the number of columns in the given two dimensional array.
+        * 
+        * This method assumes that the arrays in the given matrix all have
+        * equal lengths.
+        * 
+        * @param matrix
+        *        A two dimensional array.
+        * @return
+        *        The number of columns.
+        */
+       public static final int colsIn(float[][] matrix) {
+               return matrix.length > 0 ? matrix[0].length : 0;
+       }
+
+       /**
+        * Returns the total number of elements in the given two dimensional 
+        * array.
+        * 
+        * This method assumes that the arrays in the given matrix all have
+        * equal lengths.
+        * 
+        * @param matrix
+        *        A two dimensional array.
+        * @return
+        *        The total number of elements.
+        */
+       public static final int sizeOf(float[][] matrix) {
+               return rowsIn(matrix) * colsIn(matrix);
+       }
+}
diff --git a/Annotation/src/ie/dcu/matrix/Index2D.class b/Annotation/src/ie/dcu/matrix/Index2D.class
new file mode 100644 (file)
index 0000000..58f34ea
Binary files /dev/null and b/Annotation/src/ie/dcu/matrix/Index2D.class differ
diff --git a/Annotation/src/ie/dcu/matrix/Index2D.java b/Annotation/src/ie/dcu/matrix/Index2D.java
new file mode 100644 (file)
index 0000000..cb0ef9b
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Index2D.java
+ *
+ * Copyright (c) 2009 by Kevin McGuinness 
+ */
+package ie.dcu.matrix;
+
+import java.io.Serializable;
+
+/**
+ * An immutable class encapsulating a two dimensional index.
+ * 
+ * @author Kevin McGuinness
+ */
+public final class Index2D implements Serializable {
+       
+       /**
+        * Serialization UID.
+        */
+       private static final long serialVersionUID = 2722263604670361463L;
+       
+       /**
+        * The row index.
+        */
+       public final int i; 
+       
+       /**
+        * The column index.
+        */
+       public final int j;
+       
+       /**
+        * Create an two dimensional index for the given co-ordinates.
+        * 
+        * @param i
+        *        The row index.
+        * @param j
+        *        The column index.
+        */
+       public Index2D(int i, int j) {
+               this.i = i;
+               this.j = j;
+       }
+       
+       /**
+        * Returns true if the passed object is an Index2D and both objects are
+        * have equal values.
+        */
+       @Override
+       public boolean equals(Object o) {
+               if (o instanceof Index2D) {
+                       Index2D index = (Index2D) o;
+                       return i == index.i && j == index.j;
+               }
+               return false;
+       }
+       
+       /**
+        * Returns the hash code.
+        */
+       @Override
+       public int hashCode() {
+               return (i ^ j);
+       }
+       
+       /**
+        * Returns a string of the form i,j
+        */
+       public String toString() {
+               return String.format("%d,%d", i, j);
+       }
+}
diff --git a/Annotation/src/ie/dcu/matrix/IntMatrix.class b/Annotation/src/ie/dcu/matrix/IntMatrix.class
new file mode 100644 (file)
index 0000000..23984ec
Binary files /dev/null and b/Annotation/src/ie/dcu/matrix/IntMatrix.class differ
diff --git a/Annotation/src/ie/dcu/matrix/IntMatrix.java b/Annotation/src/ie/dcu/matrix/IntMatrix.java
new file mode 100644 (file)
index 0000000..86f6250
--- /dev/null
@@ -0,0 +1,431 @@
+/*
+ * IntMatrix.java
+ *
+ * Copyright (c) 2009 by Kevin McGuinness 
+ */
+package ie.dcu.matrix;
+
+import ie.dcu.array.Arrays;
+
+/**
+ * Two dimensional matrix of int values.
+ *
+ * @author Kevin McGuinness
+ */
+public class IntMatrix extends Matrix {
+    
+    /**
+     * Serialization UID.
+     */
+       private static final long serialVersionUID = 6142053146188137402L;
+       
+       /**
+        * Shared empty matrix 
+        */
+       private static final IntMatrix EMPTY_MATRIX = new IntMatrix(0,0);
+       
+       /**
+        * The int values of the matrix in row-major order.
+        */
+       public final int[] values;
+
+    /**
+     * Construct an uninitialized matrix of the given size.
+     *
+     * @param rows
+     *        The number of rows
+     * @param cols
+     *        The number of columns
+     */
+       public IntMatrix(int rows, int cols) {
+               super(Type.Int, rows, cols);
+               values = new int[size];
+       }
+       
+       /**
+        * Construct a matrix of the given size with the given values.
+        * 
+        * @param rows
+     *        The number of rows
+     * @param cols
+     *        The number of columns
+        * @param values
+        *        The values to the matrix will have (not copied).
+        */
+       public IntMatrix(int rows, int cols, int ... values) {          
+               super(Type.Int, rows, cols, values.length);
+               this.values = values;
+       }
+       
+       /**
+        * Construct a matrix of the given size by copying the values in the 
+        * given two dimensional array.
+        * 
+        * The passed two dimensional array must consist of arrays that have
+        * the same dimension.
+        * 
+        * @param matrix
+        *        A two dimensional array of int values.
+        * @throws IllegalArgumentException
+        *        If the matrix does not contain arrays of the same dimension.       
+        */
+       public IntMatrix(int[][] matrix) {
+               this(rowsIn(matrix), colsIn(matrix));
+               flatten(matrix, values);
+       }
+       
+       /**
+        * Returns the int value at the given row and column index.
+        *
+        * @param row
+        *        The row index.
+        * @param col
+        *        The column index.
+        * @return 
+        *        The int value at (row, col).
+        */
+       public final int intAt(int row, int col) {
+               return values[offsetOf(row, col)];
+       }
+       
+    /**
+        * Returns the int value at the index.
+        *
+        * @param index
+        *        The index
+        * @return 
+        *        The int value
+        */
+       public final int intAt(Index2D index) {
+               return values[offsetOf(index)];
+       }
+
+    /**
+        * Set the int value at the given row and column index.
+        *
+        * @param row
+        *        The row index.
+        * @param col
+        *        The column index.
+        * @param value 
+        *        The int value to set.
+        */
+       public final void setIntAt(int row, int col, int value) {
+               values[offsetOf(row, col)] = value;
+       }
+       
+       /**
+        * Set the int value at the given index.
+        *
+        * @param index
+        *        The index.
+        * @param value 
+        *        The int value to set.
+        */
+       public final void setIntAt(Index2D index, int value) {
+               values[offsetOf(index)] = value;
+       }
+       
+       /**
+        * Returns the int value at the given offset in the matrix.
+        *
+        * @param offset
+        *        The absolute offset in the matrix.
+        * @return 
+        *        The int value at the given offset.
+        */
+       public final int intAt(int offset) {
+               return values[offset];
+       }
+
+    /**
+        * Set the int value at the given offset in the matrix.
+        *
+        * @param offset
+        *        The matrix offset
+        * @param value 
+        *        The int value to set.
+        */
+       public final void setIntAt(int offset, int value) {
+               values[offset] = value;
+       }
+       
+       /**
+        * Returns the smallest int value in the matrix.
+        *
+        * @return
+        *        The smallest int value, or <code>null</code> if the 
+        *        matrix is empty.
+        */
+       public final Integer minValue() {
+           return Arrays.min(values);
+       }
+       
+       /**
+        * Returns the largest int value in the matrix.
+        *
+        * @return
+        *        The largest int value, or <code>null</code> if the 
+        *        matrix is empty.
+        */
+       public final Integer maxValue() {
+               return Arrays.max(values);
+       }
+       
+       /**
+        * Returns a transposed version of the matrix.
+        */
+       public final IntMatrix transpose() {
+               IntMatrix m = new IntMatrix(cols, rows);
+               for (int i = 0; i < rows; i++) {
+                       for (int j = 0; j < cols; j++) {
+                               m.values[offsetOf(j,i)] = values[offsetOf(i, j)];
+                       }
+               }
+               return m;
+       }
+
+    /**
+     * Returns a deep copy of the matrix.
+     */
+       @Override
+       public IntMatrix clone() {
+               return new IntMatrix(rows, cols, values.clone());
+       }
+
+    /**
+     * Returns true if both matrices are equal in value.
+     */
+       @Override
+       public boolean equals(Object obj) {
+               if (obj instanceof IntMatrix) {
+                       IntMatrix m = (IntMatrix) obj;
+                       if (sizeEquals(m)) {
+                               return java.util.Arrays.equals(values, m.values);
+                       }
+                       return false;
+               }
+               return super.equals(obj);               
+       }
+
+    /**
+     * Fills the matrix with the %{primative} value of the given number.
+     *
+     * @param number
+     *        The number to fill the matrix with (will be truncated if 
+     *        necessary).
+     * @return 
+     *        This matrix.
+     */
+       @Override
+       public final IntMatrix fill(Number number) {
+               java.util.Arrays.fill(values, number.intValue());
+               return this;
+       }
+
+    /**
+     * Returns the Integer value at the given row and column index.
+     *
+     * @param row
+        *        The row index.
+        * @param col
+        *        The column index.
+        * @return 
+        *        The Integer value at (row, col).
+     */
+       @Override
+       public final Integer valueAt(int row, int col) {
+               return values[offsetOf(row, col)];
+       }
+       
+       /**
+        * Set the Number value at the given row and column index.
+        *
+        * @param row
+        *        The row index.
+        * @param col
+        *        The column index.
+        * @param value 
+        *        The Number value to set (will be truncated if necessary).
+        */
+       @Override
+       public final void setValueAt(int row, int col, Number value) {
+               values[offsetOf(row, col)] = value.intValue();
+       }
+       
+       /**
+     * Returns the Integer value at the given matrix offset.
+     *
+     * @param offset
+     *        The absolute offset in the matrix.
+        * @return 
+        *        The Integer value at the given offset.
+     */
+       @Override
+       public final Integer valueAt(int offset) {
+               return values[offset];
+       }
+       
+       /**
+        * Set the Number value at the given matrix offset.
+        *
+        * @param offset
+        *        The absolute offset in the matrix.
+        * @param value 
+        *        The Number value to set (will be truncated if necessary).
+        */
+       @Override
+       public final void setValueAt(int offset, Number value) {
+               values[offset] = value.intValue();
+       }
+       
+       /**
+        * Returns the matrix values (not copied).
+        */
+       @Override
+       public final int[] values() {
+               return values;
+       }
+       
+       /**
+        * Returns a shared empty matrix instance.
+        */
+       public static IntMatrix empty() {
+               return EMPTY_MATRIX;
+       }
+       
+       /**
+        * Construct and return an identity matrix with the given number of rows.
+        *
+        * @param rows
+        *        The number of rows/columns for the matrix to have.
+        * @return
+        *        A new identity matrix.
+        */
+       public static IntMatrix eye(int rows) {
+               IntMatrix m = new IntMatrix(rows, rows);
+               m.fill(0);
+               for (int i = 0; i < rows; i++) {
+                       m.setIntAt(i, i, (int) 1);
+               }
+               return m;
+       }
+       
+       /**
+        * Construct and return an zero matrix with the given number of rows
+        * and columns.
+        *
+        * @param rows
+        *        The number of rows for the matrix to have.
+        * @param cols
+        *        The number of cols for the matrix to have.
+        * @return
+        *        A new zero matrix.
+        */
+       public static IntMatrix zeros(int rows, int cols) {
+               IntMatrix m = new IntMatrix(rows, rows);
+               m.fill(0);
+               return m;
+       }
+       
+       /**
+        * Construct and return a matrix of ones with the given number of rows
+        * and columns.
+        *
+        * @param rows
+        *        The number of rows for the matrix to have.
+        * @param cols
+        *        The number of cols for the matrix to have.
+        * @return
+        *        A new matrix of ones.
+        */
+       public static IntMatrix ones(int rows, int cols) {
+               IntMatrix m = new IntMatrix(rows, rows);
+               m.fill(1);
+               return m;
+       }
+       
+       /**
+     * Copy the given two dimensional array of int values into the given 
+        * array. If the passed array does not contain at enough room for the
+        * passed matrix, a new array is allocated and returned.
+        * 
+        * The passed two dimensional array must consist of arrays that have
+        * the same dimension.
+        *
+        * The copy is performed such that the flattened array is in row major
+        * order. 
+        * 
+        * @param matrix
+        *        The 2D array of int values to flatten
+        * @param array
+        *        The array to copy to (can be <code>null</code>).
+        * @return
+        *        A flattened version of the matrix.
+        * @throws IllegalArgumentException
+        *        If the matrix does not contain arrays of the same dimension.
+        */
+       public static final int[] flatten(int[][] matrix, int[] array) {
+               int rows = matrix.length;
+               int cols = matrix.length > 0 ? matrix[0].length : 0;
+               int size = rows * cols;
+
+               if (array == null || array.length < size) { 
+                       array = new int[size];
+               }
+
+               for (int i = 0; i < rows; i++) {
+
+                       if (cols != matrix[i].length) {
+                               throw new IllegalArgumentException();
+                       }
+
+                       System.arraycopy(matrix[i], 0, array, cols * i, cols);
+               }
+
+               return array;
+       }
+       
+    /**
+     * Returns the number of rows in the given two dimensional array.
+        * 
+        * @param matrix
+        *        A two dimensional array.
+        * @return
+        *        The number of rows.
+        */
+       public static final int rowsIn(int[][] matrix) {
+               return matrix.length;
+       }
+
+       /**
+        * Returns the number of columns in the given two dimensional array.
+        * 
+        * This method assumes that the arrays in the given matrix all have
+        * equal lengths.
+        * 
+        * @param matrix
+        *        A two dimensional array.
+        * @return
+        *        The number of columns.
+        */
+       public static final int colsIn(int[][] matrix) {
+               return matrix.length > 0 ? matrix[0].length : 0;
+       }
+
+       /**
+        * Returns the total number of elements in the given two dimensional 
+        * array.
+        * 
+        * This method assumes that the arrays in the given matrix all have
+        * equal lengths.
+        * 
+        * @param matrix
+        *        A two dimensional array.
+        * @return
+        *        The total number of elements.
+        */
+       public static final int sizeOf(int[][] matrix) {
+               return rowsIn(matrix) * colsIn(matrix);
+       }
+}
diff --git a/Annotation/src/ie/dcu/matrix/LongMatrix.class b/Annotation/src/ie/dcu/matrix/LongMatrix.class
new file mode 100644 (file)
index 0000000..3557ae5
Binary files /dev/null and b/Annotation/src/ie/dcu/matrix/LongMatrix.class differ
diff --git a/Annotation/src/ie/dcu/matrix/LongMatrix.java b/Annotation/src/ie/dcu/matrix/LongMatrix.java
new file mode 100644 (file)
index 0000000..190b06a
--- /dev/null
@@ -0,0 +1,431 @@
+/*
+ * LongMatrix.java
+ *
+ * Copyright (c) 2009 by Kevin McGuinness 
+ */
+package ie.dcu.matrix;
+
+import ie.dcu.array.Arrays;
+
+/**
+ * Two dimensional matrix of long values.
+ *
+ * @author Kevin McGuinness
+ */
+public class LongMatrix extends Matrix {
+    
+    /**
+     * Serialization UID.
+     */
+       private static final long serialVersionUID = 8453351009298723791L;
+       
+       /**
+        * Shared empty matrix 
+        */
+       private static final LongMatrix EMPTY_MATRIX = new LongMatrix(0,0);
+       
+       /**
+        * The long values of the matrix in row-major order.
+        */
+       public final long[] values;
+
+    /**
+     * Construct an uninitialized matrix of the given size.
+     *
+     * @param rows
+     *        The number of rows
+     * @param cols
+     *        The number of columns
+     */
+       public LongMatrix(int rows, int cols) {
+               super(Type.Long, rows, cols);
+               values = new long[size];
+       }
+       
+       /**
+        * Construct a matrix of the given size with the given values.
+        * 
+        * @param rows
+     *        The number of rows
+     * @param cols
+     *        The number of columns
+        * @param values
+        *        The values to the matrix will have (not copied).
+        */
+       public LongMatrix(int rows, int cols, long ... values) {                
+               super(Type.Long, rows, cols, values.length);
+               this.values = values;
+       }
+       
+       /**
+        * Construct a matrix of the given size by copying the values in the 
+        * given two dimensional array.
+        * 
+        * The passed two dimensional array must consist of arrays that have
+        * the same dimension.
+        * 
+        * @param matrix
+        *        A two dimensional array of long values.
+        * @throws IllegalArgumentException
+        *        If the matrix does not contain arrays of the same dimension.       
+        */
+       public LongMatrix(long[][] matrix) {
+               this(rowsIn(matrix), colsIn(matrix));
+               flatten(matrix, values);
+       }
+       
+       /**
+        * Returns the long value at the given row and column index.
+        *
+        * @param row
+        *        The row index.
+        * @param col
+        *        The column index.
+        * @return 
+        *        The long value at (row, col).
+        */
+       public final long longAt(int row, int col) {
+               return values[offsetOf(row, col)];
+       }
+       
+    /**
+        * Returns the long value at the index.
+        *
+        * @param index
+        *        The index
+        * @return 
+        *        The long value
+        */
+       public final long longAt(Index2D index) {
+               return values[offsetOf(index)];
+       }
+
+    /**
+        * Set the long value at the given row and column index.
+        *
+        * @param row
+        *        The row index.
+        * @param col
+        *        The column index.
+        * @param value 
+        *        The long value to set.
+        */
+       public final void setLongAt(int row, int col, long value) {
+               values[offsetOf(row, col)] = value;
+       }
+       
+       /**
+        * Set the long value at the given index.
+        *
+        * @param index
+        *        The index.
+        * @param value 
+        *        The long value to set.
+        */
+       public final void setLongAt(Index2D index, long value) {
+               values[offsetOf(index)] = value;
+       }
+       
+       /**
+        * Returns the long value at the given offset in the matrix.
+        *
+        * @param offset
+        *        The absolute offset in the matrix.
+        * @return 
+        *        The long value at the given offset.
+        */
+       public final long longAt(int offset) {
+               return values[offset];
+       }
+
+    /**
+        * Set the long value at the given offset in the matrix.
+        *
+        * @param offset
+        *        The matrix offset
+        * @param value 
+        *        The long value to set.
+        */
+       public final void setLongAt(int offset, long value) {
+               values[offset] = value;
+       }
+       
+       /**
+        * Returns the smallest long value in the matrix.
+        *
+        * @return
+        *        The smallest long value, or <code>null</code> if the 
+        *        matrix is empty.
+        */
+       public final Long minValue() {
+           return Arrays.min(values);
+       }
+       
+       /**
+        * Returns the largest long value in the matrix.
+        *
+        * @return
+        *        The largest long value, or <code>null</code> if the 
+        *        matrix is empty.
+        */
+       public final Long maxValue() {
+               return Arrays.max(values);
+       }
+       
+       /**
+        * Returns a transposed version of the matrix.
+        */
+       public final LongMatrix transpose() {
+               LongMatrix m = new LongMatrix(cols, rows);
+               for (int i = 0; i < rows; i++) {
+                       for (int j = 0; j < cols; j++) {
+                               m.values[offsetOf(j,i)] = values[offsetOf(i, j)];
+                       }
+               }
+               return m;
+       }
+
+    /**
+     * Returns a deep copy of the matrix.
+     */
+       @Override
+       public LongMatrix clone() {
+               return new LongMatrix(rows, cols, values.clone());
+       }
+
+    /**
+     * Returns true if both matrices are equal in value.
+     */
+       @Override
+       public boolean equals(Object obj) {
+               if (obj instanceof LongMatrix) {
+                       LongMatrix m = (LongMatrix) obj;
+                       if (sizeEquals(m)) {
+                               return java.util.Arrays.equals(values, m.values);
+                       }
+                       return false;
+               }
+               return super.equals(obj);               
+       }
+
+    /**
+     * Fills the matrix with the %{primative} value of the given number.
+     *
+     * @param number
+     *        The number to fill the matrix with (will be truncated if 
+     *        necessary).
+     * @return 
+     *        This matrix.
+     */
+       @Override
+       public final LongMatrix fill(Number number) {
+               java.util.Arrays.fill(values, number.longValue());
+               return this;
+       }
+
+    /**
+     * Returns the Long value at the given row and column index.
+     *
+     * @param row
+        *        The row index.
+        * @param col
+        *        The column index.
+        * @return 
+        *        The Long value at (row, col).
+     */
+       @Override
+       public final Long valueAt(int row, int col) {
+               return values[offsetOf(row, col)];
+       }
+       
+       /**
+        * Set the Number value at the given row and column index.
+        *
+        * @param row
+        *        The row index.
+        * @param col
+        *        The column index.
+        * @param value 
+        *        The Number value to set (will be truncated if necessary).
+        */
+       @Override
+       public final void setValueAt(int row, int col, Number value) {
+               values[offsetOf(row, col)] = value.longValue();
+       }
+       
+       /**
+     * Returns the Long value at the given matrix offset.
+     *
+     * @param offset
+     *        The absolute offset in the matrix.
+        * @return 
+        *        The Long value at the given offset.
+     */
+       @Override
+       public final Long valueAt(int offset) {
+               return values[offset];
+       }
+       
+       /**
+        * Set the Number value at the given matrix offset.
+        *
+        * @param offset
+        *        The absolute offset in the matrix.
+        * @param value 
+        *        The Number value to set (will be truncated if necessary).
+        */
+       @Override
+       public final void setValueAt(int offset, Number value) {
+               values[offset] = value.longValue();
+       }
+       
+       /**
+        * Returns the matrix values (not copied).
+        */
+       @Override
+       public final long[] values() {
+               return values;
+       }
+       
+       /**
+        * Returns a shared empty matrix instance.
+        */
+       public static LongMatrix empty() {
+               return EMPTY_MATRIX;
+       }
+       
+       /**
+        * Construct and return an identity matrix with the given number of rows.
+        *
+        * @param rows
+        *        The number of rows/columns for the matrix to have.
+        * @return
+        *        A new identity matrix.
+        */
+       public static LongMatrix eye(int rows) {
+               LongMatrix m = new LongMatrix(rows, rows);
+               m.fill(0);
+               for (int i = 0; i < rows; i++) {
+                       m.setLongAt(i, i, (long) 1);
+               }
+               return m;
+       }
+       
+       /**
+        * Construct and return an zero matrix with the given number of rows
+        * and columns.
+        *
+        * @param rows
+        *        The number of rows for the matrix to have.
+        * @param cols
+        *        The number of cols for the matrix to have.
+        * @return
+        *        A new zero matrix.
+        */
+       public static LongMatrix zeros(int rows, int cols) {
+               LongMatrix m = new LongMatrix(rows, rows);
+               m.fill(0);
+               return m;
+       }
+       
+       /**
+        * Construct and return a matrix of ones with the given number of rows
+        * and columns.
+        *
+        * @param rows
+        *        The number of rows for the matrix to have.
+        * @param cols
+        *        The number of cols for the matrix to have.
+        * @return
+        *        A new matrix of ones.
+        */
+       public static LongMatrix ones(int rows, int cols) {
+               LongMatrix m = new LongMatrix(rows, rows);
+               m.fill(1);
+               return m;
+       }
+       
+       /**
+     * Copy the given two dimensional array of long values into the given 
+        * array. If the passed array does not contain at enough room for the
+        * passed matrix, a new array is allocated and returned.
+        * 
+        * The passed two dimensional array must consist of arrays that have
+        * the same dimension.
+        *
+        * The copy is performed such that the flattened array is in row major
+        * order. 
+        * 
+        * @param matrix
+        *        The 2D array of long values to flatten
+        * @param array
+        *        The array to copy to (can be <code>null</code>).
+        * @return
+        *        A flattened version of the matrix.
+        * @throws IllegalArgumentException
+        *        If the matrix does not contain arrays of the same dimension.
+        */
+       public static final long[] flatten(long[][] matrix, long[] array) {
+               int rows = matrix.length;
+               int cols = matrix.length > 0 ? matrix[0].length : 0;
+               int size = rows * cols;
+
+               if (array == null || array.length < size) { 
+                       array = new long[size];
+               }
+
+               for (int i = 0; i < rows; i++) {
+
+                       if (cols != matrix[i].length) {
+                               throw new IllegalArgumentException();
+                       }
+
+                       System.arraycopy(matrix[i], 0, array, cols * i, cols);
+               }
+
+               return array;
+       }
+       
+    /**
+     * Returns the number of rows in the given two dimensional array.
+        * 
+        * @param matrix
+        *        A two dimensional array.
+        * @return
+        *        The number of rows.
+        */
+       public static final int rowsIn(long[][] matrix) {
+               return matrix.length;
+       }
+
+       /**
+        * Returns the number of columns in the given two dimensional array.
+        * 
+        * This method assumes that the arrays in the given matrix all have
+        * equal lengths.
+        * 
+        * @param matrix
+        *        A two dimensional array.
+        * @return
+        *        The number of columns.
+        */
+       public static final int colsIn(long[][] matrix) {
+               return matrix.length > 0 ? matrix[0].length : 0;
+       }
+
+       /**
+        * Returns the total number of elements in the given two dimensional 
+        * array.
+        * 
+        * This method assumes that the arrays in the given matrix all have
+        * equal lengths.
+        * 
+        * @param matrix
+        *        A two dimensional array.
+        * @return
+        *        The total number of elements.
+        */
+       public static final int sizeOf(long[][] matrix) {
+               return rowsIn(matrix) * colsIn(matrix);
+       }
+}
diff --git a/Annotation/src/ie/dcu/matrix/Matrix$1.class b/Annotation/src/ie/dcu/matrix/Matrix$1.class
new file mode 100644 (file)
index 0000000..c24284f
Binary files /dev/null and b/Annotation/src/ie/dcu/matrix/Matrix$1.class differ
diff --git a/Annotation/src/ie/dcu/matrix/Matrix$Type.class b/Annotation/src/ie/dcu/matrix/Matrix$Type.class
new file mode 100644 (file)
index 0000000..c4571be
Binary files /dev/null and b/Annotation/src/ie/dcu/matrix/Matrix$Type.class differ
diff --git a/Annotation/src/ie/dcu/matrix/Matrix.class b/Annotation/src/ie/dcu/matrix/Matrix.class
new file mode 100644 (file)
index 0000000..2e3fd38
Binary files /dev/null and b/Annotation/src/ie/dcu/matrix/Matrix.class differ
diff --git a/Annotation/src/ie/dcu/matrix/Matrix.java b/Annotation/src/ie/dcu/matrix/Matrix.java
new file mode 100644 (file)
index 0000000..7ff901f
--- /dev/null
@@ -0,0 +1,768 @@
+/*
+ * Matrix.java
+ *
+ * Copyright (c) 2009 by Kevin McGuinness 
+ * 
+ * TODO: Optimizations in subclasses (toXMatrix)
+ */
+package ie.dcu.matrix;
+
+import java.io.*;
+import java.util.*;
+
+import ie.dcu.array.Arrays;
+
+/**
+ * Abstract base class for two dimensional matrix types.
+ * 
+ * @author Kevin McGuinness
+ */
+public abstract class Matrix implements Cloneable, Serializable, MatrixProvider {
+       
+       /**
+        * Serialization UID.
+        */
+       private static final long serialVersionUID = 7948337494015379755L;
+       
+       /**
+        * Supported matrix types.
+        */
+       public static enum Type {
+               Byte,
+               Short,
+               Int,
+               Long,
+               Double, 
+               Float
+       };
+       
+       /**
+        * The matrix type. (never <code>null</code>).
+        */
+       public final Type type;
+       
+       /**
+        * The number of rows (height) of the matrix (always >= 0).
+        */
+       public final int rows;
+       
+       /**
+        * The number of rows (width) of the matrix (always >= 0).
+        */
+       public final int cols;
+       
+       /**
+        * The total number of elements matrix (always >= 0).
+        */
+       public final int size;
+       
+       /**
+        * Constructor for subclasses.
+        * 
+        * @param type
+        *        The matrix type (cannot be <code>null</code>).
+        * @param rows
+        *        The number or rows in the matrix (must be >= 0).
+        * @param cols
+        *        The number of columns in the matrix (must be >= 0).
+        */
+       protected Matrix(Type type, int rows, int cols) {
+               this(type, rows, cols, rows * cols);
+       }
+       
+       /**
+        * Constructor for subclasses.
+        * 
+        * The reason this constructor takes a size parameter is to allow 
+        * subclasses to easily ensure the size of a passed array is correct.
+        * 
+        * @param type
+        *        The matrix type (cannot be <code>null</code>).
+        * @param rows
+        *        The number or rows in the matrix (must be >= 0).
+        * @param cols
+        *        The number of columns in the matrix (must be >= 0).
+        * @param size
+        *        Must equal <code>rows * cols</code>.
+        */
+       protected Matrix(Type type, int rows, int cols, int size) {
+               if (type == null) {
+                       throw new IllegalArgumentException("type == null");
+               }
+               
+               if (rows < 0) {
+                       throw new IllegalArgumentException("rows < 0");
+               }
+               
+               if (cols < 0) {
+                       throw new IllegalArgumentException("cols < 0");
+               }
+               
+               if (size != rows * cols) {
+                       throw new IllegalArgumentException("size != rows * cols");
+               }
+               
+               this.type = type;
+               this.rows = rows;
+               this.cols = cols;
+               this.size = size;
+       }
+       
+       /**
+        * Returns true if the given row index is in range.
+        * 
+        * @param row
+        *        The row index
+        */
+       public final boolean hasRow(int row) {
+               return row >= 0 && row < rows;
+       }
+
+       /**
+        * Returns true if the given column index is in range.
+        * 
+        * @param col
+        *        The column index
+        */
+       public final boolean hasCol(int col) {
+               return col >= 0 && col < cols;
+       }
+
+       /**
+        * Returns true if the given row and column index are in range.
+        * 
+        * @param row
+        *        The row index
+        * @param col
+        *        The column index
+        */
+       public final boolean hasIndex(int row, int col) {
+               return row >= 0 && row < rows && col >= 0 && col < cols;
+       }
+       
+       /**
+        * Returns true if the given two dimensional index is in range.
+        * 
+        * @param index
+        *        The two dimensional index
+        */
+       public final boolean hasIndex(Index2D index) {
+               return hasIndex(index.i, index.j);
+       }
+
+       /**
+        * Returns true if the given offset is in range.
+        * 
+        * @param offset
+        *        An absolute offset into the matrix.
+        */
+       public final boolean hasOffset(int offset) {
+               return offset >= 0 && offset < size;
+       }
+       
+       /**
+        * Returns true if the given matrix is the same size as the receiver.
+        *
+        * @param m
+        *        A matrix of any type.
+        */
+       public final boolean sizeEquals(Matrix m) {
+               return rows == m.rows && cols == m.cols;
+       }
+
+       /**
+        * Returns the width (number of columns) in the matrix.
+        */
+       public final int width() {
+               return cols;
+       }
+       
+       /**
+        * Returns the height (number of rows) in the matrix.
+        */
+       public final int height() {
+               return rows;
+       }
+       
+       /**
+        * Returns the offset of the given row index.
+        * 
+        * @param row
+        *        The row index.
+        */
+       public final int offsetOf(int row) {
+               return row * cols;
+       }
+       
+       /**
+        * Returns the offset of the given row and column index.
+        * 
+        * For efficiency this method does not check if the matrix is empty. 
+        * The value col will be returned if it is.
+        * 
+        * @param row
+        *        The row index.
+        * @param col
+        *        The column index.
+        */
+       public final int offsetOf(int row, int col) {
+               return row * cols + col;
+       }
+       
+       /**
+        * Returns the offset of the given two dimensional index.
+        * 
+        * For efficiency this method does not check if the matrix is empty. 
+        * The value index.j will be returned if it is.
+        * 
+        * @param index
+        *        A two dimensional index.
+        */
+       public final int offsetOf(Index2D index) {
+               return index.i * cols + index.j;
+       }
+       
+       /**
+        * Returns the two dimensional index of the given offset.
+        * 
+        * The return value is <code>null</code> if the matrix is empty.
+        * 
+        * @param offset
+        *        An absolute offset into the matrix.
+        * @return
+        *        The two dimensional index of the offset.
+        */
+       public final Index2D indexOf(int offset) {
+               return size != 0 ? new Index2D(offset / cols, offset % cols) : null;
+       }
+       
+       /**
+        * Returns true of the matrix has zero rows or zero columns.
+        */
+       public final boolean isEmpty() {
+               return size == 0;
+       }
+       
+       /**
+        * Returns the Number value at the given row and column.
+        * 
+        * @param row 
+        *        The row index.
+        * @param col
+        *        The column index.
+        * @return
+        *        A Number value.
+        */
+       public Number valueAt(int row, int col) {
+               return valueAt(offsetOf(row, col));
+       }
+       
+       /**
+        * Returns the Number value at the given two dimensional index.
+        * 
+        * @param index
+        *        The two dimensional index.
+        * @return
+        *        A Number value.
+        */
+       public Number valueAt(Index2D index) {
+               return valueAt(offsetOf(index));
+       }
+
+       /**
+        * Set the Number value at the given row and column.
+        * 
+        * @param row 
+        *        The row index.
+        * @param col
+        *        The column index.
+        * @param value
+        *        The Number value to set.
+        */
+       public void setValueAt(int row, int col, Number value) {
+               setValueAt(offsetOf(row, col), value);
+       }
+       
+       /**
+        * Set the Number value at the given two dimensional index.
+        * 
+        * @param index
+        *        The two dimensional index
+        * @param value
+        *        The Number value to set.
+        */
+       public void setValueAt(Index2D index, Number value) {
+               setValueAt(offsetOf(index), value);
+       }
+       
+       /**
+        * Fill the matrix with the given number value.
+        * 
+        * @param number 
+        *        The number value.
+        * @return This matrix.
+        */
+       public Matrix fill(Number number) {
+               for (int i = 0; i < size; i++) {
+                       setValueAt(i, number);
+               }
+               return this;
+       }
+       
+       /**
+        * Clamp the matrix values in the given range.
+        * 
+        * @param min 
+        *        The minimum value.
+        * @param max 
+        *        The maximum value.
+        * @return This matrix.
+        */
+       public Matrix clamp(Number min, Number max) {
+               Arrays.clamp(values(), min, max);
+               return this;
+       }
+       
+       /**
+        * Returns the smallest value in the matrix. 
+        * 
+        * Comparisons are performed in double precision.
+        *
+        * @return
+        *        The smallest value, or <code>null</code> if the 
+        *        matrix is empty.
+        */
+       public Number minValue() {
+               Number min = null;
+               if (!isEmpty()) {
+                       min = valueAt(0);
+                       for (int i = 1; i < size; i++) {
+                               Number value = valueAt(i);
+                               if (value.doubleValue() < min.doubleValue()) {
+                                       min = value;
+                               }
+                       }
+               }
+               return min;
+       }
+       
+       /**
+        * Returns the largest value in the matrix.
+        * 
+        * Comparisons are performed in double precision.
+        *
+        * @return
+        *        The largest value, or <code>null</code> if the 
+        *        matrix is empty.
+        */
+       public Number maxValue() {
+               Number max = null;
+               if (!isEmpty()) {
+                       max = valueAt(0);
+                       for (int i = 1; i < size; i++) {
+                               Number value = valueAt(i);
+                               if (value.doubleValue() > max.doubleValue()) {
+                                       max = value;
+                               }
+                       }
+               }
+               return max;
+       }
+       
+       /**
+        * Find the first index containing the given number. If no such index
+        * exists, <code>null</code> is returned.
+        * 
+        * Comparison is performed using double precision floats.
+        * 
+        * @param number
+        *        A Number value.
+        * @return
+        *        The first index matching the value, or null if none is found.
+        */
+       public Index2D findFirst(Number number) {
+               double value = number.doubleValue();
+               for (int i = 0, k = 0; i < rows; i++) {
+                       for (int j = 0; j < cols; j++, k++) {
+                               if (valueAt(k).doubleValue() == value) {
+                                       return new Index2D(i, j);
+                               }
+                       }
+               }
+               return null;
+       }
+       
+       /**
+        * Find the next index containing the given number. If no such index
+        * exists, <code>null</code> is returned.
+        * 
+        * Comparison is performed using double precision floats.
+        * 
+        * @param number
+        *        A Number value.
+        * @param start
+        *        The index to start at.
+        * @return
+        *        The first index matching the value, or null if none is found.
+        */
+       public Index2D findNext(Index2D start, Number number) {
+               double value = number.doubleValue();
+               for (int i = start.i; i < rows; i++) {
+                       int k = i * cols;
+                       for (int j = start.j; j < cols; j++, k++) {
+                               
+                               if (valueAt(k).doubleValue() == value) {
+                                       return new Index2D(i, j);
+                               }
+                       }
+               }
+               return null;
+       }
+       
+       /**
+        * Find the last index containing the given number. If no such index
+        * exists, <code>null</code> is returned.
+        * 
+        * Comparison is performed using double precision floats.
+        * 
+        * @param number
+        *        A Number value.
+        * @return
+        *        The last index matching the value, or null if none is found.
+        */
+       public Index2D findLast(Number number) {
+               double value = number.doubleValue();
+               for (int i = rows - 1; i >= 0; i--) {
+                       for (int j = cols - 1; j >= 0; j--) {
+                               if (valueAt(i,j).doubleValue() == value) {
+                                       return new Index2D(i, j);
+                               }
+                       }
+               }
+               return null;
+       }
+
+       /**
+        * Find all indices containing the given number.
+        * 
+        * The returned list is ordered from first found to last, with the search
+        * starting at the top left corner of the matrix and proceeding in row major
+        * order.
+        * 
+        * Comparison is performed using double precision floats.
+        * 
+        * @param number
+        *        A Number value.
+        * @return 
+        *        A list of indices.
+        */
+       public List<Index2D> findAll(Number number) {
+               ArrayList<Index2D> indices = new ArrayList<Index2D>();
+               
+               double value = number.doubleValue();
+               for (int i = 0, k = 0; i < rows; i++) {
+                       for (int j = 0; j < cols; j++, k++) {
+                               if (valueAt(k).doubleValue() == value) {
+                                       indices.add(new Index2D(i, j));
+                               }
+                       }
+               }
+               
+               return indices;
+       }
+       
+       /**
+        * Convert to a ByteMatrix, rounding and truncating if necessary.
+        * 
+        * @return
+        *        A new ByteMatrix.
+        */
+       public ByteMatrix toByteMatrix() {
+               return toByteMatrix(null);
+       }
+       
+       /**
+        * Convert to a ByteMatrix, rounding and truncating if necessary.
+        * 
+        * If the specified matrix is <code>null</code> or not the same
+        * size as this matrix, a new matrix is allocated.
+        * 
+        * @param matrix
+        *        The matrix to copy to.
+        * @return
+        *        A new ByteMatrix.
+        */
+       public ByteMatrix toByteMatrix(ByteMatrix matrix) {
+               if (matrix == null || !sizeEquals(matrix)) {
+                       matrix = new ByteMatrix(rows, cols);    
+               } 
+               
+               Arrays.copy(values(), matrix.values);
+               return matrix;
+       }
+       
+       /**
+        * Convert to a ShortMatrix, rounding and truncating if necessary.
+        * 
+        * @return
+        *        A new ShortMatrix.
+        */
+       public ShortMatrix toShortMatrix() {
+               return toShortMatrix(null);
+       }
+       
+       /**
+        * Convert to a ShortMatrix, rounding and truncating if necessary.
+        * 
+        * If the specified matrix is <code>null</code> or not the same
+        * size as this matrix, a new matrix is allocated.
+        * 
+        * @param matrix
+        *        The matrix to copy to.
+        * @return
+        *        A new ShortMatrix.
+        */
+       public ShortMatrix toShortMatrix(ShortMatrix matrix) {
+               if (matrix == null || !sizeEquals(matrix)) {
+                       matrix = new ShortMatrix(rows, cols);   
+               } 
+               
+               Arrays.copy(values(), matrix.values);
+               return matrix;
+       }
+       
+       /**
+        * Convert to an IntMatrix, rounding and truncating if necessary.
+        * 
+        * @return
+        *        A new IntMatrix.
+        */
+       public IntMatrix toIntMatrix() {
+               return toIntMatrix(null);
+       }
+       
+       /**
+        * Convert to a IntMatrix, rounding and truncating if necessary.
+        * 
+        * If the specified matrix is <code>null</code> or not the same
+        * size as this matrix, a new matrix is allocated.
+        * 
+        * @param matrix
+        *        The matrix to copy to.
+        * @return
+        *        A new IntMatrix.
+        */
+       public IntMatrix toIntMatrix(IntMatrix matrix) {
+               if (matrix == null || !sizeEquals(matrix)) {
+                       matrix = new IntMatrix(rows, cols);     
+               } 
+               
+               Arrays.copy(values(), matrix.values);
+               return matrix;
+       }
+       
+       /**
+        * Convert to a LongMatrix, rounding and truncating if necessary.
+        * 
+        * @return
+        *        A new LongMatrix.
+        */
+       public LongMatrix toLongMatrix() {
+               return toLongMatrix(null);
+       }
+       
+       /**
+        * Convert to a LongMatrix, rounding and truncating if necessary.
+        * 
+        * If the specified matrix is <code>null</code> or not the same
+        * size as this matrix, a new matrix is allocated.
+        * 
+        * @param matrix
+        *        The matrix to copy to.
+        * @return
+        *        A new LongMatrix.
+        */
+       public LongMatrix toLongMatrix(LongMatrix matrix) {
+               if (matrix == null || !sizeEquals(matrix)) {
+                       matrix = new LongMatrix(rows, cols);    
+               } 
+               
+               Arrays.copy(values(), matrix.values);
+               return matrix;
+       }
+       
+       /**
+        * Convert to an FloatMatrix, rounding if necessary.
+        * 
+        * @return
+        *        A new FloatMatrix.
+        */
+       public FloatMatrix toFloatMatrix() {
+               return toFloatMatrix(null);
+       }
+       
+       /**
+        * Convert to an FloatMatrix, rounding if necessary.
+        * 
+        * If the specified matrix is <code>null</code> or not the same
+        * size as this matrix, a new matrix is allocated.
+        * 
+        * @param matrix
+        *        The matrix to copy to.
+        * @return
+        *        A new FloatMatrix.
+        */
+       public FloatMatrix toFloatMatrix(FloatMatrix matrix) {
+               if (matrix == null || !sizeEquals(matrix)) {
+                       matrix = new FloatMatrix(rows, cols);   
+               } 
+               
+               Arrays.copy(values(), matrix.values);
+               return matrix;
+       }
+       
+       /**
+        * Convert to an DoubleMatrix, rounding if necessary.
+        * 
+        * @return
+        *        A new DoubleMatrix.
+        */
+       public DoubleMatrix toDoubleMatrix() {
+               return toDoubleMatrix(null);
+       }
+       
+       /**
+        * Convert to an DoubleMatrix, rounding if necessary.
+        * 
+        * If the specified matrix is <code>null</code> or not the same
+        * size as this matrix, a new matrix is allocated.
+        * 
+        * @param matrix
+        *        The matrix to copy to.
+        * @return
+        *        A new DoubleMatrix.
+        */
+       public DoubleMatrix toDoubleMatrix(DoubleMatrix matrix) {
+               if (matrix == null || !sizeEquals(matrix)) {
+                       matrix = new DoubleMatrix(rows, cols);  
+               } 
+               
+               Arrays.copy(values(), matrix.values);
+               return matrix;
+       }
+       
+       /**
+        * Returns the Number value at the given offset.
+        * 
+        * @param offset
+        *        An absolute offset into the matrix.
+        * @return
+        *        The Number value at the offset.
+        */
+       public abstract Number valueAt(int offset);
+       
+       /**
+        * Set the Number value at the given offset.
+        * 
+        * @param offset
+        *        An absolute offset into the matrix.
+        * @param value
+        *        The number value to set.
+        */
+       public abstract void setValueAt(int offset, Number value);
+
+       /**
+        * Returns true of the matrices are the same size and have equal values.
+        */
+       @Override
+       public boolean equals(Object obj) {
+               if (obj instanceof Matrix) {
+                       Matrix m = (Matrix) obj;
+                       
+                       if (sizeEquals(m)) {
+                               for (int i = 0; i < size; i++) {
+                                       if (!valueAt(i).equals(m.valueAt(i))) {
+                                               return false;
+                                       }
+                               }
+                               return true;
+                       }
+               }
+               
+               return false;
+       }
+       
+       /**
+        * Returns the array of matrix values. The return type is dependent
+        * on the subclass, so Object is given here.
+        * 
+        * @return The array of values.
+        */
+       public abstract Object values();
+
+       /**
+        * Returns a string representation of the matrix.
+        */
+       @Override
+       public String toString() {
+               String header = String.format("%dx%d Matrix (%s)", rows, cols, type);
+               if (rows < 10 && cols < 10) {
+                       // Show the whole matrix
+                       StringBuffer s = new StringBuffer(header);
+                       s.append(" = [\n");
+                       MatrixFormatter f = new MatrixFormatter();
+                       f.format(this, s);
+                       s.append(" ]");
+                       return s.toString();
+               }
+               return header;
+       }
+       
+       /*
+        * (non-Javadoc)
+        * @see ie.dcu.cdvp.matrix.MatrixProvider#getDefaultMatrixType()
+        */
+       public Type getDefaultMatrixType() {
+               return type;
+       }
+
+       /*
+        * (non-Javadoc)
+        * @see ie.dcu.cdvp.matrix.MatrixProvider#getMatrix(boolean)
+        */
+       public Matrix getMatrix(boolean alwaysCopy) {
+               return getMatrix(null, alwaysCopy);
+       }
+
+       /*
+        * (non-Javadoc)
+        * @see ie.dcu.cdvp.matrix.MatrixProvider#getMatrix(ie.dcu.cdvp.matrix.Matrix.Type, boolean)
+        */
+       public Matrix getMatrix(Type type, boolean alwaysCopy) {
+               
+               if (type == null || type == this.type) {
+                       try {
+                               return (alwaysCopy) ? (Matrix) clone() : this;
+                       } catch (CloneNotSupportedException e) {
+                               throw new RuntimeException(e);
+                       }
+               }
+               
+               switch (type) {
+               case Byte:
+                       return toByteMatrix();
+               case Short:
+                       return toShortMatrix();
+               case Int:
+                       return toIntMatrix();
+               case Long:
+                       return toLongMatrix();
+               case Float:
+                       return toFloatMatrix();
+               case Double:
+                       return toDoubleMatrix();
+               default:
+                       throw new UnsupportedOperationException();
+               }
+       }
+}
diff --git a/Annotation/src/ie/dcu/matrix/MatrixFormatter$1.class b/Annotation/src/ie/dcu/matrix/MatrixFormatter$1.class
new file mode 100644 (file)
index 0000000..6f84be4
Binary files /dev/null and b/Annotation/src/ie/dcu/matrix/MatrixFormatter$1.class differ
diff --git a/Annotation/src/ie/dcu/matrix/MatrixFormatter.class b/Annotation/src/ie/dcu/matrix/MatrixFormatter.class
new file mode 100644 (file)
index 0000000..58eb28c
Binary files /dev/null and b/Annotation/src/ie/dcu/matrix/MatrixFormatter.class differ
diff --git a/Annotation/src/ie/dcu/matrix/MatrixFormatter.java b/Annotation/src/ie/dcu/matrix/MatrixFormatter.java
new file mode 100644 (file)
index 0000000..724a770
--- /dev/null
@@ -0,0 +1,295 @@
+package ie.dcu.matrix;
+
+/**
+ * Handles formating matrices so that all columns are equal width.
+ * 
+ * @author Kevin McGuinness
+ */
+public class MatrixFormatter {
+       
+       private static final String NaN = "NaN";
+       private static final String Inf = "Inf";
+       
+       // Options
+       private boolean supressSmallValues;
+       private boolean signAlwaysShown;
+       private int precision;
+       
+       // Internal variables
+       private boolean expFormat;
+       private boolean largeExponent;
+       private String numberFormat;
+       private String specialFormat;
+       private int maxStrLen;
+       
+       public MatrixFormatter() {
+               
+               // Setup defaults
+               supressSmallValues = false;
+               signAlwaysShown = false;
+               precision = 8;
+       }
+
+       public boolean isSupressSmallValues() {
+               return supressSmallValues;
+       }
+
+       public void setSupressSmallValues(boolean value) {
+               this.supressSmallValues = value;
+       }
+
+       public boolean isSignAlwaysShown() {
+               return signAlwaysShown;
+       }
+
+       public void setSignAlwaysShown(boolean value) {
+               this.signAlwaysShown = value;
+       }
+
+       public int getPrecision() {
+               return precision;
+       }
+
+       public void setPrecision(int precision) {
+               if (precision < 0) {
+                       throw new IllegalArgumentException("precision < 0");
+               }
+               this.precision = precision;
+       }
+
+       public String format(Matrix m) {
+               return format(m, null).toString();
+       }
+
+       public StringBuffer format(Matrix m, StringBuffer s) {
+               if (s == null) {
+                       s = new StringBuffer();
+               }
+               
+               if (!m.isEmpty()) {
+                       switch (m.type) {
+                       case Byte:
+                       case Short:
+                       case Int:
+                       case Long:
+                               formatIntegerMatrix(m, s);
+                               break;
+                       default:
+                               formatDecimalMatrix(m, s);
+                               break;
+                       }
+               }
+               
+               return s;
+       }
+
+       public static String toString(Matrix m) {
+               return new MatrixFormatter().format(m, null).toString();
+       }
+
+       private void formatIntegerMatrix(Matrix m, StringBuffer s) {
+               analyseIntegerMatrix(m);
+               
+               for (int i = 0; i < m.rows; i++) {
+                       for (int j = 0; j < m.cols; j++) {
+                               long value = m.valueAt(i, j).longValue();
+                               s.append(formatValue(value));
+                       }
+                       if (i != m.rows - 1) {
+                               s.append('\n');
+                       }
+               }
+       }
+       
+       private void formatDecimalMatrix(Matrix m, StringBuffer s) {
+               analyseDecimalMatrix(m);
+               
+               for (int i = 0; i < m.rows; i++) {
+                       for (int j = 0; j < m.cols; j++) {
+                               double v = m.valueAt(i, j).doubleValue();
+                               s.append(formatValue(v));
+                       }
+                       if (i != m.rows - 1) {
+                               s.append('\n');
+                       }
+               }
+       }
+       
+       private String formatValue(double v) {
+               if (Double.isNaN(v)) {
+                       return String.format(specialFormat, NaN);
+               } 
+               
+               if (Double.isInfinite(v)) {
+                       return String.format(specialFormat, v < 0 ? "-" + Inf : Inf);
+               }
+               
+               StringBuilder s = new StringBuilder(String.format(numberFormat, v));
+               
+               if (largeExponent) {    
+                       char sign = s.charAt(s.length()-4);
+                       if (sign == '+' || sign == '-') {
+                               s.insert(s.length()-3, '0');
+                       }
+                       
+               } else if (expFormat) {
+                       if (s.charAt(s.length()-4) == '0') {
+                               s.deleteCharAt(s.length()-4);
+                       }
+                       s.insert(0, ' ');
+               } else if (v != 0) {
+                       while (s.charAt(s.length()-1) == '0' && s.charAt(s.length()-2) != '.') {
+                               s.deleteCharAt(s.length()-1);
+                               s.insert(0, ' ');
+                       }
+               }
+               
+               return s.toString();
+       }
+       
+       private String formatValue(long value) {
+               return String.format(numberFormat, value);
+       }
+       
+       private void analyseIntegerMatrix(Matrix m) {
+               long min = m.maxValue().longValue();
+               long max = m.minValue().longValue();
+               
+               int digits = Math.max(
+                               String.valueOf(min).length(), 
+                               String.valueOf(max).length());
+               
+               maxStrLen = digits + 1;
+               if (min >= 0 && signAlwaysShown) {
+                       maxStrLen++;
+               }
+               
+               StringBuilder nfmt = new StringBuilder("%");
+               
+               if (signAlwaysShown) {
+                       nfmt.append('+');
+               }
+               
+               nfmt.append(maxStrLen);
+               nfmt.append('d');
+               numberFormat = nfmt.toString();
+       }
+       
+       private void analyseDecimalMatrix(Matrix m) {
+               expFormat = false;
+               largeExponent = false;
+               
+               boolean hasSpecial = false;
+               boolean hasNonZero = false;
+               double minAbsNzVal = Double.MAX_VALUE;
+               double maxAbsNzVal = Double.MIN_VALUE;
+               
+               for (int i = 0; i < m.size; i++) {
+                       double value = m.valueAt(i).doubleValue();
+                       
+                       if (Double.isNaN(value) || Double.isInfinite(value)) {
+                               hasSpecial = true;
+                               continue;
+                       } 
+                       
+                       if (value != 0.0) {
+                               hasNonZero = true;
+                               
+                               double abs = Math.abs(value);
+                               
+                               if (abs < minAbsNzVal) {
+                                       minAbsNzVal = abs;
+                               }
+                               
+                               if (abs > maxAbsNzVal) {
+                                       maxAbsNzVal = abs;
+                               }
+                       }
+               }
+               
+               if (hasNonZero) {
+                       
+                       if (maxAbsNzVal > 1e8) {
+                               expFormat = true;
+                       }
+                       
+                       if (!supressSmallValues) {
+                               if (minAbsNzVal < 0.0001 || maxAbsNzVal / minAbsNzVal > 1000.0) {
+                                       expFormat = true;
+                               }
+                       }
+                       
+               } else {
+                       
+                       maxAbsNzVal = 0.0;
+                       minAbsNzVal = 0.0;
+               }
+       
+               int truePrecision = precision;
+               
+               if (expFormat) {
+                       maxStrLen = 8 + truePrecision;
+                       
+                       if ((minAbsNzVal >= 0 && minAbsNzVal < 1e-99) || maxAbsNzVal > 1e100) {
+                               largeExponent = true;
+                               maxStrLen++;
+                       }
+                       
+               } else {
+                       
+                       if (hasNonZero) {
+                               String fmt = String.format("%%.%df", precision);
+                               truePrecision = maxDigitCount(fmt, m, precision);
+                       } else {
+                               truePrecision = 0;
+                       }
+                       
+                       truePrecision = Math.min(precision, truePrecision);
+                       int intLength = String.valueOf((long) maxAbsNzVal).length();
+                       maxStrLen = intLength + truePrecision + 3;
+                       
+                       if (hasSpecial) {
+                               int maxSpecialLen = Math.max(NaN.length(), Inf.length()+1);
+                               maxStrLen = Math.max(maxStrLen, maxSpecialLen);
+                       }
+               }
+               
+               // Compute number format
+               StringBuffer nfmt = new StringBuffer("%");
+               nfmt.append(signAlwaysShown ? "+" : "");
+               nfmt.append(maxStrLen);
+               nfmt.append('.');
+               nfmt.append(truePrecision);
+               nfmt.append(expFormat? 'e' : 'f');
+               numberFormat = nfmt.toString();
+               
+               // Compute special format
+               StringBuffer sfmt = new StringBuffer("%");
+               sfmt.append(maxStrLen);
+               sfmt.append('s');
+               specialFormat = sfmt.toString();
+       }
+
+       private static int maxDigitCount(String format, Matrix m, int precision) {
+               int max = 0;
+               for (int i = 0; i < m.size; i++) {
+                       double v = m.valueAt(i).doubleValue();
+                       if (!Double.isNaN(v) && !Double.isInfinite(v) && v != 0) {
+                               int count = digitCount(format, v, precision);
+                               if (count > max) {
+                                       max = count;
+                               }
+                       }
+               }
+               return max;
+       }
+       
+       private static int digitCount(String format, double value, int precision) {
+               String s = String.format(format, value);
+               StringBuilder z = new StringBuilder(s);
+               while (z.length() > 0 && z.charAt(z.length()-1) == '0') {
+                       z.deleteCharAt(z.length()-1);
+               }
+               return precision - s.length() + z.length(); 
+       }
+}
diff --git a/Annotation/src/ie/dcu/matrix/MatrixProvider.class b/Annotation/src/ie/dcu/matrix/MatrixProvider.class
new file mode 100644 (file)
index 0000000..233f822
Binary files /dev/null and b/Annotation/src/ie/dcu/matrix/MatrixProvider.class differ
diff --git a/Annotation/src/ie/dcu/matrix/MatrixProvider.java b/Annotation/src/ie/dcu/matrix/MatrixProvider.java
new file mode 100644 (file)
index 0000000..774d625
--- /dev/null
@@ -0,0 +1,41 @@
+package ie.dcu.matrix;
+
+/**
+ * Interface for classes that can provide matrices.
+ * 
+ * @author Kevin McGuinness
+ */
+public interface MatrixProvider {
+       
+       /**
+        * Returns the default type created by this matrix provider if no type
+        * is specified when calling <code>getMatrix()</code>. This may be null
+        * if it is unknown.
+        * 
+        * @return The default matrix type.
+        */
+       public Matrix.Type getDefaultMatrixType();
+       
+       /**
+        * Request a matrix from the matrix provider.
+        * 
+        * @param alwaysCopy
+        *            If <code>true</code> the a copy is always returned, otherwise
+        *            the matrix may or may not be a copy.
+        * @return A matrix.
+        */
+       public Matrix getMatrix(boolean alwaysCopy);
+       
+       /**
+        * Request a matrix of the given type from the matrix provider.
+        * 
+        * @param type
+        *            The matrix type. If <code>null</code> then the most convenient
+        *            type for the receiver will be returned.
+        * @param alwaysCopy
+        *            If <code>true</code> the a copy is always returned, otherwise
+        *            the matrix may or may not be a copy.
+        * @return A matrix.
+        */
+       public Matrix getMatrix(Matrix.Type type, boolean alwaysCopy);
+}
diff --git a/Annotation/src/ie/dcu/matrix/ShortMatrix.class b/Annotation/src/ie/dcu/matrix/ShortMatrix.class
new file mode 100644 (file)
index 0000000..41c3f65
Binary files /dev/null and b/Annotation/src/ie/dcu/matrix/ShortMatrix.class differ
diff --git a/Annotation/src/ie/dcu/matrix/ShortMatrix.java b/Annotation/src/ie/dcu/matrix/ShortMatrix.java
new file mode 100644 (file)
index 0000000..22b0896
--- /dev/null
@@ -0,0 +1,431 @@
+/*
+ * ShortMatrix.java
+ *
+ * Copyright (c) 2009 by Kevin McGuinness 
+ */
+package ie.dcu.matrix;
+
+import ie.dcu.array.Arrays;
+
+/**
+ * Two dimensional matrix of short values.
+ *
+ * @author Kevin McGuinness
+ */
+public class ShortMatrix extends Matrix {
+    
+    /**
+     * Serialization UID.
+     */
+       private static final long serialVersionUID = 515302276679708530L;
+       
+       /**
+        * Shared empty matrix 
+        */
+       private static final ShortMatrix EMPTY_MATRIX = new ShortMatrix(0,0);
+       
+       /**
+        * The short values of the matrix in row-major order.
+        */
+       public final short[] values;
+
+    /**
+     * Construct an uninitialized matrix of the given size.
+     *
+     * @param rows
+     *        The number of rows
+     * @param cols
+     *        The number of columns
+     */
+       public ShortMatrix(int rows, int cols) {
+               super(Type.Short, rows, cols);
+               values = new short[size];
+       }
+       
+       /**
+        * Construct a matrix of the given size with the given values.
+        * 
+        * @param rows
+     *        The number of rows
+     * @param cols
+     *        The number of columns
+        * @param values
+        *        The values to the matrix will have (not copied).
+        */
+       public ShortMatrix(int rows, int cols, short ... values) {              
+               super(Type.Short, rows, cols, values.length);
+               this.values = values;
+       }
+       
+       /**
+        * Construct a matrix of the given size by copying the values in the 
+        * given two dimensional array.
+        * 
+        * The passed two dimensional array must consist of arrays that have
+        * the same dimension.
+        * 
+        * @param matrix
+        *        A two dimensional array of short values.
+        * @throws IllegalArgumentException
+        *        If the matrix does not contain arrays of the same dimension.       
+        */
+       public ShortMatrix(short[][] matrix) {
+               this(rowsIn(matrix), colsIn(matrix));
+               flatten(matrix, values);
+       }
+       
+       /**
+        * Returns the short value at the given row and column index.
+        *
+        * @param row
+        *        The row index.
+        * @param col
+        *        The column index.
+        * @return 
+        *        The short value at (row, col).
+        */
+       public final short shortAt(int row, int col) {
+               return values[offsetOf(row, col)];
+       }
+       
+    /**
+        * Returns the short value at the index.
+        *
+        * @param index
+        *        The index
+        * @return 
+        *        The short value
+        */
+       public final short shortAt(Index2D index) {
+               return values[offsetOf(index)];
+       }
+
+    /**
+        * Set the short value at the given row and column index.
+        *
+        * @param row
+        *        The row index.
+        * @param col
+        *        The column index.
+        * @param value 
+        *        The short value to set.
+        */
+       public final void setShortAt(int row, int col, short value) {
+               values[offsetOf(row, col)] = value;
+       }
+       
+       /**
+        * Set the short value at the given index.
+        *
+        * @param index
+        *        The index.
+        * @param value 
+        *        The short value to set.
+        */
+       public final void setShortAt(Index2D index, short value) {
+               values[offsetOf(index)] = value;
+       }
+       
+       /**
+        * Returns the short value at the given offset in the matrix.
+        *
+        * @param offset
+        *        The absolute offset in the matrix.
+        * @return 
+        *        The short value at the given offset.
+        */
+       public final short shortAt(int offset) {
+               return values[offset];
+       }
+
+    /**
+        * Set the short value at the given offset in the matrix.
+        *
+        * @param offset
+        *        The matrix offset
+        * @param value 
+        *        The short value to set.
+        */
+       public final void setShortAt(int offset, short value) {
+               values[offset] = value;
+       }
+       
+       /**
+        * Returns the smallest short value in the matrix.
+        *
+        * @return
+        *        The smallest short value, or <code>null</code> if the 
+        *        matrix is empty.
+        */
+       public final Short minValue() {
+           return Arrays.min(values);
+       }
+       
+       /**
+        * Returns the largest short value in the matrix.
+        *
+        * @return
+        *        The largest short value, or <code>null</code> if the 
+        *        matrix is empty.
+        */
+       public final Short maxValue() {
+               return Arrays.max(values);
+       }
+       
+       /**
+        * Returns a transposed version of the matrix.
+        */
+       public final ShortMatrix transpose() {
+               ShortMatrix m = new ShortMatrix(cols, rows);
+               for (int i = 0; i < rows; i++) {
+                       for (int j = 0; j < cols; j++) {
+                               m.values[offsetOf(j,i)] = values[offsetOf(i, j)];
+                       }
+               }
+               return m;
+       }
+
+    /**
+     * Returns a deep copy of the matrix.
+     */
+       @Override
+       public ShortMatrix clone() {
+               return new ShortMatrix(rows, cols, values.clone());
+       }
+
+    /**
+     * Returns true if both matrices are equal in value.
+     */
+       @Override
+       public boolean equals(Object obj) {
+               if (obj instanceof ShortMatrix) {
+                       ShortMatrix m = (ShortMatrix) obj;
+                       if (sizeEquals(m)) {
+                               return java.util.Arrays.equals(values, m.values);
+                       }
+                       return false;
+               }
+               return super.equals(obj);               
+       }
+
+    /**
+     * Fills the matrix with the %{primative} value of the given number.
+     *
+     * @param number
+     *        The number to fill the matrix with (will be truncated if 
+     *        necessary).
+     * @return 
+     *        This matrix.
+     */
+       @Override
+       public final ShortMatrix fill(Number number) {
+               java.util.Arrays.fill(values, number.shortValue());
+               return this;
+       }
+
+    /**
+     * Returns the Short value at the given row and column index.
+     *
+     * @param row
+        *        The row index.
+        * @param col
+        *        The column index.
+        * @return 
+        *        The Short value at (row, col).
+     */
+       @Override
+       public final Short valueAt(int row, int col) {
+               return values[offsetOf(row, col)];
+       }
+       
+       /**
+        * Set the Number value at the given row and column index.
+        *
+        * @param row
+        *        The row index.
+        * @param col
+        *        The column index.
+        * @param value 
+        *        The Number value to set (will be truncated if necessary).
+        */
+       @Override
+       public final void setValueAt(int row, int col, Number value) {
+               values[offsetOf(row, col)] = value.shortValue();
+       }
+       
+       /**
+     * Returns the Short value at the given matrix offset.
+     *
+     * @param offset
+     *        The absolute offset in the matrix.
+        * @return 
+        *        The Short value at the given offset.
+     */
+       @Override
+       public final Short valueAt(int offset) {
+               return values[offset];
+       }
+       
+       /**
+        * Set the Number value at the given matrix offset.
+        *
+        * @param offset
+        *        The absolute offset in the matrix.
+        * @param value 
+        *        The Number value to set (will be truncated if necessary).
+        */
+       @Override
+       public final void setValueAt(int offset, Number value) {
+               values[offset] = value.shortValue();
+       }
+       
+       /**
+        * Returns the matrix values (not copied).
+        */
+       @Override
+       public final short[] values() {
+               return values;
+       }
+       
+       /**
+        * Returns a shared empty matrix instance.
+        */
+       public static ShortMatrix empty() {
+               return EMPTY_MATRIX;
+       }
+       
+       /**
+        * Construct and return an identity matrix with the given number of rows.
+        *
+        * @param rows
+        *        The number of rows/columns for the matrix to have.
+        * @return
+        *        A new identity matrix.
+        */
+       public static ShortMatrix eye(int rows) {
+               ShortMatrix m = new ShortMatrix(rows, rows);
+               m.fill(0);
+               for (int i = 0; i < rows; i++) {
+                       m.setShortAt(i, i, (short) 1);
+               }
+               return m;
+       }
+       
+       /**
+        * Construct and return an zero matrix with the given number of rows
+        * and columns.
+        *
+        * @param rows
+        *        The number of rows for the matrix to have.
+        * @param cols
+        *        The number of cols for the matrix to have.
+        * @return
+        *        A new zero matrix.
+        */
+       public static ShortMatrix zeros(int rows, int cols) {
+               ShortMatrix m = new ShortMatrix(rows, rows);
+               m.fill(0);
+               return m;
+       }
+       
+       /**
+        * Construct and return a matrix of ones with the given number of rows
+        * and columns.
+        *
+        * @param rows
+        *        The number of rows for the matrix to have.
+        * @param cols
+        *        The number of cols for the matrix to have.
+        * @return
+        *        A new matrix of ones.
+        */
+       public static ShortMatrix ones(int rows, int cols) {
+               ShortMatrix m = new ShortMatrix(rows, rows);
+               m.fill(1);
+               return m;
+       }
+       
+       /**
+     * Copy the given two dimensional array of short values into the given 
+        * array. If the passed array does not contain at enough room for the
+        * passed matrix, a new array is allocated and returned.
+        * 
+        * The passed two dimensional array must consist of arrays that have
+        * the same dimension.
+        *
+        * The copy is performed such that the flattened array is in row major
+        * order. 
+        * 
+        * @param matrix
+        *        The 2D array of short values to flatten
+        * @param array
+        *        The array to copy to (can be <code>null</code>).
+        * @return
+        *        A flattened version of the matrix.
+        * @throws IllegalArgumentException
+        *        If the matrix does not contain arrays of the same dimension.
+        */
+       public static final short[] flatten(short[][] matrix, short[] array) {
+               int rows = matrix.length;
+               int cols = matrix.length > 0 ? matrix[0].length : 0;
+               int size = rows * cols;
+
+               if (array == null || array.length < size) { 
+                       array = new short[size];
+               }
+
+               for (int i = 0; i < rows; i++) {
+
+                       if (cols != matrix[i].length) {
+                               throw new IllegalArgumentException();
+                       }
+
+                       System.arraycopy(matrix[i], 0, array, cols * i, cols);
+               }
+
+               return array;
+       }
+       
+    /**
+     * Returns the number of rows in the given two dimensional array.
+        * 
+        * @param matrix
+        *        A two dimensional array.
+        * @return
+        *        The number of rows.
+        */
+       public static final int rowsIn(short[][] matrix) {
+               return matrix.length;
+       }
+
+       /**
+        * Returns the number of columns in the given two dimensional array.
+        * 
+        * This method assumes that the arrays in the given matrix all have
+        * equal lengths.
+        * 
+        * @param matrix
+        *        A two dimensional array.
+        * @return
+        *        The number of columns.
+        */
+       public static final int colsIn(short[][] matrix) {
+               return matrix.length > 0 ? matrix[0].length : 0;
+       }
+
+       /**
+        * Returns the total number of elements in the given two dimensional 
+        * array.
+        * 
+        * This method assumes that the arrays in the given matrix all have
+        * equal lengths.
+        * 
+        * @param matrix
+        *        A two dimensional array.
+        * @return
+        *        The total number of elements.
+        */
+       public static final int sizeOf(short[][] matrix) {
+               return rowsIn(matrix) * colsIn(matrix);
+       }
+}
diff --git a/Annotation/src/ie/dcu/plugin/JarResource.class b/Annotation/src/ie/dcu/plugin/JarResource.class
new file mode 100644 (file)
index 0000000..f7c0fe3
Binary files /dev/null and b/Annotation/src/ie/dcu/plugin/JarResource.class differ
diff --git a/Annotation/src/ie/dcu/plugin/Plugin.class b/Annotation/src/ie/dcu/plugin/Plugin.class
new file mode 100644 (file)
index 0000000..18e551b
Binary files /dev/null and b/Annotation/src/ie/dcu/plugin/Plugin.class differ
diff --git a/Annotation/src/ie/dcu/plugin/Plugin.java b/Annotation/src/ie/dcu/plugin/Plugin.java
new file mode 100644 (file)
index 0000000..38d835f
--- /dev/null
@@ -0,0 +1,57 @@
+package ie.dcu.plugin;
+
+import java.io.File;
+import java.net.URLClassLoader;
+import java.util.Map;
+
+public class Plugin {
+       private final File root;
+       private final Map<String, String> metadata;
+       private final URLClassLoader loader;
+
+       Plugin(File root, Map<String, String> metadata, URLClassLoader loader) {
+               this.root = root;
+               this.metadata = metadata;
+               this.loader = loader;
+       }
+       
+       public String getName() {
+               return getMetadata("name");
+       }
+       
+       public Map<String, String> getMetadata() {
+               return metadata;
+       }
+       
+       public String getMetadata(String key) {
+               return metadata.get(key);
+       }
+       
+       public File getRootFolder() {
+               return root;
+       }
+       
+       public File getResource(String name) {
+               return new File(root, name);
+       }
+       
+       public Class<?> loadClass(String name) throws ClassNotFoundException {
+               return loader.loadClass(name);
+       }
+       
+       public Object loadObject(String name) 
+               throws PluginException 
+       {
+               try {
+                       Class<?> clazz = loadClass(name);
+                       Object instance = clazz.newInstance();
+                       return instance;
+               } catch (ClassNotFoundException e) {
+                       throw new PluginException(e);
+               } catch (InstantiationException e) {
+                       throw new PluginException(e);
+               } catch (IllegalAccessException e) {
+                       throw new PluginException(e);
+               }
+       }
+}
diff --git a/Annotation/src/ie/dcu/plugin/PluginClassLoader.class b/Annotation/src/ie/dcu/plugin/PluginClassLoader.class
new file mode 100644 (file)
index 0000000..f054574
Binary files /dev/null and b/Annotation/src/ie/dcu/plugin/PluginClassLoader.class differ
diff --git a/Annotation/src/ie/dcu/plugin/PluginClassLoader.java b/Annotation/src/ie/dcu/plugin/PluginClassLoader.java
new file mode 100644 (file)
index 0000000..2c29fc5
--- /dev/null
@@ -0,0 +1,72 @@
+package ie.dcu.plugin;
+
+import ie.dcu.util.OsUtils;
+
+import java.io.File;
+import java.net.*;
+
+public class PluginClassLoader extends URLClassLoader {
+
+       private final File root;
+
+       public PluginClassLoader(File root, URL[] urls, ClassLoader parent) {
+               super(urls, parent);
+               this.root = root;
+       }
+
+       @Override
+       protected String findLibrary(String libname) {
+               String path = findLibrary0(libname);
+               System.out.println("findLibrary: " + libname + " => " + path);
+               return path;
+       }
+       
+       private String[] getPossibleLibraryNames(String libname) {
+               if (OsUtils.isLinux64()) {
+                       return new String[] {
+                               libname, 
+                               System.mapLibraryName(libname + "64"),
+                               System.mapLibraryName(libname)
+                       };
+               } else {
+                       return new String[] {
+                               libname, 
+                               System.mapLibraryName(libname)
+                       };
+               }
+       }
+       
+       private String findLibrary0(String libname) {
+               String path;
+               
+               // Get a list of potential library names
+               String[] libnames = getPossibleLibraryNames(libname);
+               
+               // Try plugin base folder
+               if ((path = getPathIfExists(root, libnames)) != null) {
+                       return path;
+               }
+               
+               // Try plugin lib/ subfolder
+               File libFolder = new File(root, "lib");
+               if (libFolder.isDirectory()) {
+                       if ((path = getPathIfExists(libFolder, libnames)) != null) {
+                               return path;
+                       }
+               }
+               
+               // Pass off to the superclass
+               return super.findLibrary(libname);
+       }
+       
+       private String getPathIfExists(File root, String[] filenames) {
+               for (String filename : filenames) {
+                       File file = new File(root, filename);
+                       if (file.isFile()) {
+                               return file.getAbsolutePath();
+                       }
+               }
+               return null;
+       }
+               
+}
diff --git a/Annotation/src/ie/dcu/plugin/PluginException.class b/Annotation/src/ie/dcu/plugin/PluginException.class
new file mode 100644 (file)
index 0000000..1a0f5ce
Binary files /dev/null and b/Annotation/src/ie/dcu/plugin/PluginException.class differ
diff --git a/Annotation/src/ie/dcu/plugin/PluginException.java b/Annotation/src/ie/dcu/plugin/PluginException.java
new file mode 100644 (file)
index 0000000..320dc67
--- /dev/null
@@ -0,0 +1,21 @@
+package ie.dcu.plugin;
+
+public class PluginException extends Exception {
+       private static final long serialVersionUID = 1L;
+
+       public PluginException() {
+       }
+
+       public PluginException(String message) {
+               super(message);
+       }
+
+       public PluginException(Throwable cause) {
+               super(cause);
+       }
+
+       public PluginException(String message, Throwable cause) {
+               super(message, cause);
+       }
+
+}
diff --git a/Annotation/src/ie/dcu/plugin/PluginLoader$1.class b/Annotation/src/ie/dcu/plugin/PluginLoader$1.class
new file mode 100644 (file)
index 0000000..5ed0dad
Binary files /dev/null and b/Annotation/src/ie/dcu/plugin/PluginLoader$1.class differ
diff --git a/Annotation/src/ie/dcu/plugin/PluginLoader$SaxHandler.class b/Annotation/src/ie/dcu/plugin/PluginLoader$SaxHandler.class
new file mode 100644 (file)
index 0000000..2b0c560
Binary files /dev/null and b/Annotation/src/ie/dcu/plugin/PluginLoader$SaxHandler.class differ
diff --git a/Annotation/src/ie/dcu/plugin/PluginLoader.class b/Annotation/src/ie/dcu/plugin/PluginLoader.class
new file mode 100644 (file)
index 0000000..6acabbd
Binary files /dev/null and b/Annotation/src/ie/dcu/plugin/PluginLoader.class differ
diff --git a/Annotation/src/ie/dcu/plugin/PluginLoader.java b/Annotation/src/ie/dcu/plugin/PluginLoader.java
new file mode 100644 (file)
index 0000000..802c437
--- /dev/null
@@ -0,0 +1,159 @@
+package ie.dcu.plugin;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+
+import org.xml.sax.*;
+import org.xml.sax.helpers.*;
+
+public class PluginLoader {
+       public static final String SPECFILE = "plugin.xml";
+       
+       private final File root;
+       private final Map<String, String> metadata;
+       private final List<JarResource> jarFiles;
+       private URLClassLoader pluginClassLoader;
+       
+       public PluginLoader(File root) {
+               this.root = root;
+               this.metadata = new HashMap<String, String>();
+               this.jarFiles = new ArrayList<JarResource>();
+               
+               // Extract plugin name
+               String name = root.getName();
+               int idx = name.lastIndexOf('.');
+               if (idx > 1) {
+                       name = name.substring(0, idx);
+               }
+               metadata.put("name", name);
+       }
+       
+       public File getRootFolder() {
+               return root;
+       }
+       
+       public File getSpecFile() {
+               return new File(root, SPECFILE);
+       }
+       
+       public Map<String, String> getMetadata() {
+               return metadata;
+       }
+       
+       public String getMetaValue(String key) {
+               return metadata.get(key);
+       }
+       
+       public Plugin load() throws PluginException {
+               try {
+                       loadMetadata();
+                       loadJars();
+                       return new Plugin(root, metadata, pluginClassLoader);
+               } catch (SAXException e) {
+                       throw new PluginException(e);
+               } catch (IOException e) {
+                       throw new PluginException(e);
+               }
+       }
+       
+       public Class<?> loadClass(String name) throws ClassNotFoundException {
+               if (pluginClassLoader == null) {
+                       throw new IllegalStateException("load() not called");
+               }
+               return pluginClassLoader.loadClass(name);
+       }
+
+       private void addJarFile(String path) throws MalformedURLException {
+               jarFiles.add(new JarResource(root, path));
+       }
+
+       private void addMetadata(String key, String value) {
+               metadata.put(key, value);
+       }
+
+       private void loadMetadata() throws SAXException, IOException {
+               BufferedReader reader = new BufferedReader(
+                       new FileReader(getSpecFile()));
+               try {
+                       InputSource source = new InputSource(reader);
+                       XMLReader xmlreader = XMLReaderFactory.createXMLReader();
+                       xmlreader.setContentHandler(new SaxHandler());
+                       xmlreader.parse(source);
+               } finally {
+                       reader.close();
+               }
+       }
+
+       private void loadJars() {
+               URL[] jarUrls = new URL[jarFiles.size()];
+               int i = 0;
+               for (JarResource resource : jarFiles) {
+                       jarUrls[i++] = resource.url;
+               }
+               ClassLoader parent = getClass().getClassLoader();
+               pluginClassLoader = new PluginClassLoader(root, jarUrls, parent);
+       }
+
+       private class SaxHandler extends DefaultHandler {
+               private Attributes attrs;
+               private String elem;
+               
+               String getMandatoryAttribute(String name) throws SAXException {
+                       String value = attrs.getValue(name);
+                       if (value == null) {
+                               exception("Missing mandatory attribute '%s'", name);
+                       }
+                       return value;
+               }
+               
+               private void exception(String message, Object ... args) 
+                       throws SAXException {
+                       String a = String.format(message, args);
+                       String m = String.format("In element <%s>: %s", elem, a);
+                       throw new SAXException(m);
+               }
+
+               public void startElement(String uri, String localName, String name,
+                       Attributes attributes) throws SAXException {
+                       elem = name;
+                       attrs = attributes;
+                       parseElem();
+               }
+
+               private void parseElem() throws SAXException {
+                       if (elem.equals("meta")) {
+                               String name = getMandatoryAttribute("name");
+                               String value = getMandatoryAttribute("value");
+                               addMetadata(name, value);
+                       } else if (elem.equals("jar")) {
+                               String path = getMandatoryAttribute("file");
+                               try {
+                                       addJarFile(path);
+                               } catch (MalformedURLException e) {
+                                       throw new SAXException(e);
+                               }
+                                
+                       } else {
+                               // Ignore other elements
+                       }
+               }
+       }
+}
+
+class JarResource {
+       public final File file;
+       public final URI uri;
+       public final URL url;
+
+       public JarResource(File root, String path) throws MalformedURLException {
+               if (new File(path).isAbsolute()) {
+                       this.file = new File(path);
+               } else {
+                       this.file = new File(root, path);
+               }
+               uri = file.toURI();
+               url = uri.toURL();
+       }
+}
+
diff --git a/Annotation/src/ie/dcu/plugin/PluginManager.class b/Annotation/src/ie/dcu/plugin/PluginManager.class
new file mode 100644 (file)
index 0000000..c011b36
Binary files /dev/null and b/Annotation/src/ie/dcu/plugin/PluginManager.class differ
diff --git a/Annotation/src/ie/dcu/plugin/PluginManager.java b/Annotation/src/ie/dcu/plugin/PluginManager.java
new file mode 100644 (file)
index 0000000..02991ad
--- /dev/null
@@ -0,0 +1,78 @@
+package ie.dcu.plugin;
+
+import java.io.File;
+import java.util.*;
+import java.util.logging.Logger;
+
+/**
+ * I should probably use OSGi or something for this, but I couldn't be
+ * bothered...
+ * 
+ * 
+ * @author Kevin McGuinness
+ */
+public class PluginManager {
+       private static final Logger log = Logger.getLogger("PluginManager");
+       private List<String> searchPath;
+       private List<Plugin> plugins;
+       
+       public PluginManager() {
+               searchPath = new ArrayList<String>();
+               plugins = new ArrayList<Plugin>();
+       }
+       
+       public List<String> searchPath() {
+               return searchPath;
+       }
+       
+       public List<Plugin> plugins() {
+               return Collections.unmodifiableList(plugins);
+       }
+       
+       public void loadPlugins() {
+               for (String folder : searchPath()) {
+                       loadPluginsFrom(folder);
+               }
+       }
+
+       private void loadPluginsFrom(String path) {
+               log.info("Loading plugins from: " + path);
+               File file = new File(path);
+               if (file.isDirectory()) {
+                       loadPluginFromFromFolder(file);
+               } 
+       }
+       
+       private void loadPluginFromFromFolder(File file) {
+               for (File f : file.listFiles()) {
+                       if (f.isDirectory() && f.getName().endsWith(".plugin")) {
+                               loadPlugin(f);
+                       }
+               }
+       }
+       
+       public boolean hasPlugin(File pluginFolder) {
+               String name = pluginFolder.getName();
+               for (Plugin p : plugins) {
+                       if (p.getRootFolder().getName().equals(name)) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+
+       private void loadPlugin(File pluginFile) {
+               if (!hasPlugin(pluginFile)) {
+                       log.info("Loading plugin: " + pluginFile.getName());
+                       PluginLoader loader = new PluginLoader(pluginFile);                     
+                       try {
+                               Plugin plugin = loader.load();
+                               plugins.add(plugin);
+                       } catch (PluginException ex) {
+                               log.severe("Error loading plugin: " + ex.getMessage());
+                       }
+               } else {
+                       log.info("Skipping plugin (already loaded): " + pluginFile.getName());
+               }
+       }
+}
diff --git a/Annotation/src/ie/dcu/segment/SegmentationContext.class b/Annotation/src/ie/dcu/segment/SegmentationContext.class
new file mode 100644 (file)
index 0000000..96e0b84
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/SegmentationContext.class differ
diff --git a/Annotation/src/ie/dcu/segment/SegmentationContext.java b/Annotation/src/ie/dcu/segment/SegmentationContext.java
new file mode 100644 (file)
index 0000000..229d3c2
--- /dev/null
@@ -0,0 +1,377 @@
+package ie.dcu.segment;
+
+import ie.dcu.segment.annotate.*;
+import ie.dcu.segment.util.*;
+import ie.dcu.swt.SwtUtils;
+import ie.dcu.util.FileUtils;
+
+import java.io.*;
+import java.util.zip.*;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * Instances of this class manage the context of an interactive segmentation
+ * task. A segmentation context object is passed to an instance of
+ * {@link Segmenter} when the segmentation is initialized or updated. The
+ * segmentation context encapsulates the image being segmented, the current
+ * segmentation mask, the and the annotations that have been applied to the
+ * image.
+ * 
+ * 
+ * @author Kevin McGuinness
+ */
+public class SegmentationContext {
+
+       /**
+        * The file extension given to a this object when it is saved on a disk
+        */
+       public static final String EXTENSION = ".ctx";
+
+       /**
+        * The original image data
+        */
+       private final ImageData imageData;
+
+       /**
+        * The file that the context was loaded from or last saved to... this is
+        * either the original image or a segmentation context file
+        */
+       private File file;
+
+       // lazy create (use getters for these fields)
+       private AnnotationManager annotations;
+       private SegmentationMask mask;
+       private Image image;
+       private Rectangle bounds;
+
+       /**
+        * Internal constructor to create an instance of the segmentation context
+        * from the given image data object and a file object.
+        * 
+        * @param imageData
+        *        The image data object.
+        * @param file
+        *        The file from which the image data was loaded.
+        */
+       private SegmentationContext(ImageData imageData, File file) {
+               this.imageData = imageData;
+               this.file = file;
+       }
+
+       /**
+        * Returns <code>true</code> if the receiver is associated with an existing
+        * segmentation context file.
+        */
+       public boolean hasContextFile() {
+               return isContextFile(file);
+       }
+
+       /**
+        * Returns the file associated with the receiver. This is either the file
+        * that the receiver was last stored to, or the image file that was used to
+        * create the context.
+        */
+       public File getFile() {
+               return file;
+       }
+
+       /**
+        * Get the folder containing the file associated with the receiver.
+        * 
+        * @see #getFile()
+        */
+       public File getFolder() {
+               return file.getParentFile();
+       }
+
+       /**
+        * Return an appropriate filename that can be used for saving the receiver.
+        * 
+        * @see #save(File)
+        */
+       public String getDefaultFilename() {
+
+               String name = file.getName();
+               if (hasContextFile()) {
+                       return name;
+               }
+               return FileUtils.replaceExtension(name, EXTENSION);
+       }
+
+       /**
+        * Returns the current annotations that have been applied to the image.
+        * 
+        * These annotations can be converted to a raster using the
+        * {@link AnnotationRasterizer} utility class.
+        * 
+        * @return An instance of {@link AnnotationManager}
+        */
+       public AnnotationManager getAnnotations() {
+               if (annotations == null) {
+                       annotations = new AnnotationManager();
+               }
+               return annotations;
+       }
+
+       /**
+        * Returns the bounds of the current image and segmentation mask.
+        * 
+        * @return An SWT Rectangle instance.
+        */
+       public Rectangle getBounds() {
+               if (bounds == null) {
+                       bounds = new Rectangle(0, 0, imageData.width, imageData.height);
+               }
+               return bounds;
+       }
+
+       /**
+        * Returns the current segmentation mask.
+        * 
+        * @return A {@link SegmentationMask} instance.
+        */
+       public SegmentationMask getMask() {
+               if (mask == null) {
+                       mask = new SegmentationMask(getBounds());
+               }
+               return mask;
+       }
+
+       /**
+        * Returns the current image being segmented. This method returns an an SWT
+        * Image instance, constructing it if it is not already available. The
+        * {@link #getImageData()} method returns an SWT ImageData representation of
+        * the current image.
+        * 
+        * @see #getImageData()
+        */
+       public Image getImage() {
+               if (image == null || image.isDisposed()) {
+                       image = new Image(Display.getCurrent(), imageData);
+               }
+               return image;
+       }
+
+       /**
+        * Returns the image data. This is the preferred way of obtaining the image
+        * pixels since it will never create a new SWT Image instance. The utility
+        * classes {@link ImageArgbConverter} and {@link ImageByteConverter} can be
+        * used to convert the image data to a pixel array.
+        * 
+        * @return An SWT ImageData instance.
+        */
+       public ImageData getImageData() {
+               return imageData;
+       }
+
+       /**
+        * Disposes of the SWT Image instance, if it exists. The Image instance will
+        * be recreated the next time {@link #getImage()} is called.
+        */
+       public void dispose() {
+               // Dispose image
+               if (image != null && !image.isDisposed()) {
+                       image.dispose();
+                       image = null;
+               }
+       }
+
+       /**
+        * Returns <code>true</code> if the SWT Image managed by the receiver is
+        * disposed.
+        */
+       public boolean isDisposed() {
+               if (image != null) {
+                       return image.isDisposed();
+               }
+               return true;
+       }
+
+       /**
+        * Create a new segmentation by loading the an image from the given file.
+        * JPG, PNG, GIF, and BMP images are supported.
+        * 
+        * @param image
+        *        An image file.
+        * @return A new segmentation context object.
+        * @throws IOException
+        *         If the segmentation context cannot be created.
+        */
+       public static SegmentationContext create(File image) throws IOException {
+
+               // Create a new segmentation context
+               return new SegmentationContext(SwtUtils.loadImageData(image), image);
+       }
+
+       /**
+        * Save the receiver to the given file. The context can be loaded again at a
+        * later stage using the {@link #load(File)} method.
+        * 
+        * <p>
+        * The saved context is essentially a ZIP file that contains a PNG
+        * representation of the current image, a PNG representation of the current
+        * mask file, and a binary representation of the current annotations.
+        * </p>
+        * 
+        * @param file
+        *        A file.
+        * @throws IOException
+        *         If there is error saving the receiver to the given file.
+        */
+       public void save(File file) throws IOException {
+               // Based on zip file format
+               ZipOutputStream out = new ZipOutputStream(new FileOutputStream(file));
+
+               try {
+                       // Low (fast) compression.. most of data is PNG compressed anyway
+                       out.setLevel(0);
+
+                       // Create an entry for the image
+                       ZipEntry entry = new ZipEntry("image.png");
+
+                       // Start the entry
+                       out.putNextEntry(entry);
+
+                       // Store the image
+                       SwtUtils.saveImage(getImageData(), out, SWT.IMAGE_PNG);
+
+                       // End the entry
+                       out.closeEntry();
+
+                       // Create an entry for the mask
+                       entry = new ZipEntry("mask.png");
+
+                       // Start the entry
+                       out.putNextEntry(entry);
+
+                       // Save the mask
+                       getMask().save(out);
+
+                       // End the entry
+                       out.closeEntry();
+
+                       // Create an entry for the annotations
+                       entry = new ZipEntry("markup.dat");
+
+                       // Put next entry
+                       out.putNextEntry(entry);
+
+                       // Store the markup
+                       getAnnotations().save(out);
+
+                       // close entry
+                       out.closeEntry();
+
+               } finally {
+
+                       // Close
+                       out.close();
+
+                       // Set new filename
+                       this.file = file;
+               }
+       }
+
+       /**
+        * Load a segmentation context object from the disk.
+        * 
+        * @param file
+        *        A file containing the saved context.
+        * @return A new segmentation context object.
+        * @throws IOException
+        *         If there is an error loading the segmentation context file.
+        */
+       public static SegmentationContext load(File file) throws IOException {
+               ZipInputStream in = new ZipInputStream(new BufferedInputStream(
+                       new FileInputStream(file)));
+
+               ImageData imageData = null;
+               SegmentationMask mask = null;
+               AnnotationManager annotations = null;
+
+               try {
+                       ZipEntry entry;
+                       while ((entry = in.getNextEntry()) != null) {
+
+                               String name = entry.getName();
+
+                               if (name.equals("image.png")) {
+                                       imageData = SwtUtils.loadImageData(in);
+
+                               } else if (name.equals("mask.png")) {
+                                       mask = SegmentationMask.read(in);
+
+                               } else if (name.equals("markup.dat")) {
+                                       annotations = new AnnotationManager();
+                                       annotations.load(in);
+                               }
+
+                               in.closeEntry();
+                       }
+
+               } finally {
+                       in.close();
+               }
+
+               if (imageData == null) {
+                       throw new IOException("No image found in context file");
+               }
+
+               if (mask == null) {
+                       throw new IOException("No mask found in context file");
+               }
+
+               if (annotations == null) {
+                       throw new IOException("No annotations found in context file");
+               }
+
+               SegmentationContext ctx = new SegmentationContext(imageData, file);
+
+               ctx.mask = mask;
+               ctx.annotations = annotations;
+
+               return ctx;
+       }
+
+       /**
+        * Static method that checks if the given file appears to be a segmentation
+        * context file.
+        * 
+        * @param file
+        *        A file.
+        * @return <code>true</code> if the file appears to be a stored segmentation
+        *         context file.
+        */
+       public static boolean isContextFile(File file) {
+               if (file != null) {
+                       String name = file.getName().toLowerCase();
+                       return name.endsWith(EXTENSION);
+               }
+               return false;
+       }
+
+       /**
+        * Add an annotation listener. This method simply forwards the call to the
+        * {@link AnnotationManager} class.
+        * 
+        * @param listener
+        *        An {@link AnnotationListener} instance.
+        */
+       public void addAnnotationListener(AnnotationListener listener) {
+               getAnnotations().addAnnotationListener(listener);
+       }
+
+       /**
+        * Remove an annotation listener. This method simply forwards the call to
+        * the {@link AnnotationManager} class.
+        * 
+        * @param listener
+        *        An {@link AnnotationListener} instance.
+        */
+       public void removeAnnotationListener(AnnotationListener listener) {
+               getAnnotations().removeAnnotationListener(listener);
+       }
+}
diff --git a/Annotation/src/ie/dcu/segment/SegmentationMask.class b/Annotation/src/ie/dcu/segment/SegmentationMask.class
new file mode 100644 (file)
index 0000000..4fd1dc9
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/SegmentationMask.class differ
diff --git a/Annotation/src/ie/dcu/segment/SegmentationMask.java b/Annotation/src/ie/dcu/segment/SegmentationMask.java
new file mode 100644 (file)
index 0000000..6546cc5
--- /dev/null
@@ -0,0 +1,495 @@
+package ie.dcu.segment;
+
+import ie.dcu.matrix.ByteMatrix;
+
+import java.io.*;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+
+
+/**
+ * Class that represents a segmentation mask.
+ * 
+ * A segmentation mask is a two dimensional matrix of byte values. It is used
+ * to represents which pixels in an image that are part of the foreground, and 
+ * which are part of the background.
+ * 
+ * @author Kevin McGuinness
+ */
+public final class SegmentationMask extends ByteMatrix {
+       
+       /**
+        * Serialization UID
+        */
+       private static final long serialVersionUID = 4110412128756091726L;
+
+
+       /**
+        * Constant value for an unknown pixel.
+        */
+       public static final byte UNKNOWN = 0;
+       
+       
+       /**
+        * Constant value for a foreground pixel.
+        */
+       public static final byte FOREGROUND = 1;
+       
+       
+       /**
+        * Constant value of a background pixel.
+        */
+       public static final byte BACKGROUND = 2;
+
+       
+       /**
+        * The width of the segmentation mask.
+        */
+       public final int width;
+       
+       
+       /**
+        * The height of the segmentation mask.
+        */
+       public final int height;
+
+
+       /**
+        * Create a segmentation mask using the specified dimensions. All pixels in
+        * the mask are initially set to {@link SegmentationMask#UNKNOWN}.
+        * 
+        * @param width
+        *          The width.
+        * @param height
+        *          The height.
+        */
+       public SegmentationMask(int width, int height) {
+               super(height, width);
+               this.width = width;
+               this.height = height;
+               clear();
+       }
+       
+       
+       /**
+        * Create a segmentation mask using the specified dimensions. All pixels in
+        * the mask are initially set to {@link SegmentationMask#UNKNOWN}.
+        * 
+        * @param bounds
+        *          The bounds, only the width and height are used.
+        */
+       public SegmentationMask(Rectangle bounds) {
+               this(bounds.width, bounds.height);
+       }
+       
+       
+       /**
+        * Set all pixels in the mask to UNKNOWN.
+        */
+       public final void clear() {
+               fill(UNKNOWN);
+       }
+
+
+       /**
+        * Get the offset of pixel (x, y).
+        * 
+        * @param x
+        *          The x-coordinate.
+        * @param y
+        *          The y-coordinate.
+        * @return The offset of pixel at (x, y).
+        */
+       public final int offsetOfPixel(int x, int y) {
+               return x + y * width;
+       }
+
+
+       /**
+        * Set the pixel at (x,y) to the given type. The type must be one of:
+        * 
+        * <ul>
+        *      <li> {@link SegmentationMask#FOREGROUND} </li>
+        *  <li> {@link SegmentationMask#BACKGROUND} </li>
+        *  <li> {@link SegmentationMask#UNKNOWN} </li>
+        * </ul>
+        * 
+        * <b>Note:</b> This method does not check the type for correctness.
+        * <p>
+        * 
+        * @param x
+        *          The x-coordinate.
+        * @param y
+        *          The y-coordinate.
+        * @param type
+        *          The type.
+        */
+       public final void setPixel(int x, int y, byte type) {
+               values[x + y * width] = type;
+       }
+
+
+       /**
+        * Get the type of pixel at position (x, y).
+        * 
+        * @see SegmentationMask#setPixel(int, int, byte)
+        * 
+        * @param x
+        *          The x-coordinate.
+        * @param y
+        *          The y-coordinate.
+        * @return The type of pixel.
+        */
+       public final byte getPixel(int x, int y) {
+               return values[x + y * width];
+       }
+       
+       
+       /**
+        * Returns true if the mask doesn't contain any foreground
+        * or background pixels (All pixels are UNKNOWN)
+        * 
+        * @return <code>true</code> for an unknown mask.
+        */
+       public final boolean isUnknown() {
+               for (int i = 0; i < size; i++) {
+                       switch (values[i]) {
+                       case FOREGROUND:
+                       case BACKGROUND:
+                               return false;
+                       }
+               }
+               return true;
+       }
+       
+       
+       /**
+        * Check if the image contains valid pixel values.
+        * 
+        * @return <code>true</code> if the image contains valid pixel values.
+        */
+       public final boolean check() {
+               for (int i = 0; i < size; i++) {
+                       switch (values[i]) {
+                       case UNKNOWN:
+                       case FOREGROUND:
+                       case BACKGROUND:
+                               continue;
+                       default:
+                               return false;
+                       }
+               }
+               return true;
+       }
+
+
+       /**
+        * Get the bounds of the mask.
+        * 
+        * @return The bounds.
+        */
+       public final Rectangle getBounds() {
+               return new Rectangle(0, 0, width, height);
+       }
+       
+       
+       /**
+        * Returns a string representation of the mask.
+        */
+       public String toString() {
+               return String.format("SegmentationMask{ %d, %d }", width, height);
+       }
+       
+       
+       /**
+        * Save the segmentation mask as a PNG image.
+        * 
+        * @param file
+        *          The file to save it to.
+        * @throws IOException
+        *           If the mask cannot be saved for some reason.
+        */
+       public void save(File file) throws IOException {
+               
+               // Check if file is a directory
+               if (file.isDirectory()) {
+                       throw new FileNotFoundException(String.format("%s is a directory", file));
+               }
+               
+               // Check if we can write to file
+               if (file.exists()) {
+                       if (!file.canWrite()) {
+                               throw new IOException(String.format("Cannot write to %s", file));
+                       }
+               }
+               
+               // Check pixels are ok
+               if (!check()) {
+                       throw new IOException("Image contains invalid pixels, cannot save");
+               }
+               
+               // Create image loader
+               ImageLoader loader = new ImageLoader();
+               
+               // Set loader data
+               loader.data = new ImageData[] { createImageData() };
+               
+               try {
+                       // Save image
+                       loader.save(file.getAbsolutePath(), SWT.IMAGE_PNG);
+               
+               } catch (SWTException e) {
+                       // Change unchecked exception to checked one
+                       throw new IOException("SWT Exception: " + e.getMessage());
+               } 
+               
+               // Done
+               return;
+       }
+       
+       /**
+        * Store the segmentation mask to an output stream as a PNG image.
+        * 
+        * @param out
+        *          The output stream.
+        * @throws IOException
+        *           If an error occurs while saving.
+        */
+       public void save(OutputStream out) throws IOException {
+               
+               // Check pixels are ok
+               if (!check()) {
+                       throw new IOException("Image contains invalid pixels, cannot save");
+               }
+
+               // Create image loader
+               ImageLoader loader = new ImageLoader();
+               
+               // Set loader data
+               loader.data = new ImageData[] { createImageData() };
+               
+               try {
+                       // Save image
+                       loader.save(out, SWT.IMAGE_PNG);
+               
+               } catch (SWTException e) {
+                       // Change unchecked exception to checked one
+                       throw new IOException("SWT Exception: " + e.getMessage());
+               } 
+       }
+       
+       /**
+        * Create an SWT ImageData object from the mask.
+        */
+       private ImageData createImageData() {
+               // Create palette
+               PaletteData palette = getPalette();
+               
+               // Create 8 bit indexed image
+               ImageData data = new ImageData(width, height, 8, palette);
+               
+               // Blit pixels
+               for (int y = 0; y < data.height; y++) {
+                       int off1 = y * width;
+                       int off2 = y * data.bytesPerLine;
+                       System.arraycopy(this.values, off1, data.data, off2, width);
+               }
+               
+               return data;
+       }
+       
+       
+       /**
+        * Load the mask from a PNG image.
+        * 
+        * @param file
+        *          The file to load from.
+        * @throws IOException
+        *           If the mask cannot be loaded for some reason.
+        */
+       public void load(File file) throws IOException {
+               load(loadImageData(file));
+       }
+
+
+       /**
+        * Load the mask from a PNG image.
+        * 
+        * @param file
+        *          The file to load from.
+        * @return The mask
+        * @throws IOException
+        *           If the mask cannot be loaded for some reason.
+        */
+       public static SegmentationMask read(File file) throws IOException {
+               // Load image data
+               ImageData data = loadImageData(file);
+               
+               // Create compatible mask
+               SegmentationMask mask = new SegmentationMask(data.width, data.height);
+               
+               // Load data into the mask
+               mask.load(data);
+               
+               // Done
+               return mask;
+       }
+
+       /**
+        * Load the mask from a stream containing a PNG image.
+        * 
+        * @param in
+        *          The stream.
+        * @return The mask
+        * @throws IOException
+        *           If the mask cannot be loaded for some reason.
+        */
+       public static SegmentationMask read(InputStream in) throws IOException {
+               // Load image data
+               ImageData data = loadImageData(in);
+               
+               // Create compatible mask
+               SegmentationMask mask = new SegmentationMask(data.width, data.height);
+               
+               // Load data into the mask
+               mask.load(data);
+               
+               // Done
+               return mask;
+       }
+
+       
+       private static ImageData loadImageData(File file) throws IOException {
+               // Ensure file exists
+               if (!file.exists()) {
+                       throw new FileNotFoundException(String.format("%s does not exist", file));
+               }
+               
+               ImageLoader loader = new ImageLoader();
+               
+               // Load pixels
+               ImageData[] images;
+               try {
+                       images = loader.load(file.getAbsolutePath());
+               } catch (SWTException e) {
+                       
+                       // Change unchecked exception to checked one
+                       throw new IOException("SWTException: " + e.getMessage());
+               }
+               
+               // Ensure we have at least one image
+               if (images.length < 1) {
+                       throw new IOException(String.format("No images found in %s", file));
+               }
+               
+               // Grab image data
+               return images[0];
+       }
+       
+       
+       private static ImageData loadImageData(InputStream in) throws IOException {
+               ImageLoader loader = new ImageLoader();
+               
+               // Load pixels
+               ImageData[] images;
+               try {
+                       images = loader.load(in);
+               } catch (SWTException e) {
+                       
+                       // Change unchecked exception to checked one
+                       throw new IOException("SWTException: " + e.getMessage());
+               }
+               
+               // Ensure we have at least one image
+               if (images.length < 1) {
+                       throw new IOException(String.format("No images found in stream"));
+               }
+               
+               // Grab image data
+               return images[0];
+       }
+
+
+       private void load(ImageData data) throws IOException {
+               
+               // Check dimensions
+               if (width != data.width || height != data.height) {
+                       throw new IOException(
+                                       String.format("Invalid dimensions (%d,%d)", data.width, data.height));
+               }
+               
+               // Check if we have the original format
+               if (data.palette.isDirect || data.depth != 8) {
+                       
+                       // Okay we definitely don't, do it the slow way
+                       paletteTranslateLoad(data);
+                       
+               } else {
+               
+                       // Assume that we do have the original pixels and copy pixels
+                       blitLoad(data);
+                       
+                       // Test our assumption
+                       if (!check()) {
+                               
+                               // We were wrong
+                               paletteTranslateLoad(data);
+                       }
+               }
+                       
+               // Check pixels are valid
+               if (!check()) {
+                       throw new IOException("Image contains invalid pixels");
+               }
+       }
+
+
+       private void blitLoad(ImageData data) {
+               for (int y = 0; y < data.height; y++) { 
+                       int off1 = y * data.bytesPerLine;
+                       int off2 = y * width;
+                       System.arraycopy(data.data, off1, this.values, off2, width);
+               }
+       }
+
+
+       private void paletteTranslateLoad(ImageData data) {
+               PaletteData palette = getPalette();
+               
+               for (int y = 0; y < height; y++) { 
+                       int yoff = y * width;
+                       
+                       for (int x = 0; x < width; x++) {
+                               
+                               // Palette translation
+                               int pel = data.getPixel(x, y);
+                               RGB rgb = data.palette.getRGB(pel);
+                               
+                               // Check for valid rgb, use background pixel on fail
+                               int val = BACKGROUND; 
+                               for (int i = 0; i < palette.colors.length; i++) {
+                                       if (palette.colors[i].equals(rgb)) {
+                                               val = i;
+                                               break;
+                                       }
+                               }
+                               
+                               // Set
+                               this.values[x+yoff] = (byte) val;
+                       }
+               }
+       }
+       
+       
+       private PaletteData getPalette() {
+               RGB[] colors = new RGB[] {
+                               new RGB(128,128,128), 
+                               new RGB(255, 255, 255), 
+                               new RGB(0,0,0) 
+               };
+               
+               // Create palette
+               return new PaletteData(colors);
+       }
+}
diff --git a/Annotation/src/ie/dcu/segment/Segmenter.class b/Annotation/src/ie/dcu/segment/Segmenter.class
new file mode 100644 (file)
index 0000000..16dd641
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/Segmenter.class differ
diff --git a/Annotation/src/ie/dcu/segment/Segmenter.java b/Annotation/src/ie/dcu/segment/Segmenter.java
new file mode 100644 (file)
index 0000000..a29bea7
--- /dev/null
@@ -0,0 +1,136 @@
+package ie.dcu.segment;
+
+import ie.dcu.segment.SegmentationContext;
+import ie.dcu.segment.annotate.Annotation;
+import ie.dcu.segment.options.Option;
+import ie.dcu.segment.util.AbstractSegmenter;
+
+import java.util.Collection;
+
+/**
+ * The interface that interactive segmentation algorithms are required to
+ * implement.
+ * 
+ * Algorithm implementors can alternatively extend the {@link AbstractSegmenter}
+ * class.
+ * 
+ * 
+ * @author Kevin McGuinness
+ * @version 1.1
+ */
+public interface Segmenter {
+       
+       /**
+        * Implementors should return <code>true</code> if the segmentation is
+        * available on the current platform. If, for example, the segmentation
+        * algorithm requires native libraries, and there are no such libraries
+        * compiled for the current platform, this method should return
+        * <code>false</code>.
+        * 
+        * @return <code>true</code> if the algorithm is available on this platform,
+        *         <code>false</code> otherwise.
+        */
+       public boolean isAvailable();
+
+       /**
+        * Returns the name of the segmentation algorithm.
+        * 
+        * @return The segmentation algorithm name. (never <code>null</code>).
+        */
+       public String getName();
+
+
+       /**
+        * Returns a short description of the segmentation algorithm.
+        * 
+        * @return A description (never <code>null</code>).
+        */
+       public String getDescription();
+       
+       
+       /**
+        * Returns the name of the author or vendor.
+        * 
+        * @return The vendor.
+        */
+       public String getVendor();
+       
+       
+       /**
+        * Returns <code>true</code> if the algorithm is "fast". Implementors should 
+        * return <code>true</code> if a call to update typically takes less that a
+        * second. Otherwise <code>false</code> should be returned. If the speed varies
+        * or you are unsure, return <code>false</code>.
+        * 
+        * @return <code>true</code> if the algorithm performs fast updates.
+        */
+       public boolean isFast();
+       
+       
+       /**
+        * Get the options (parameters) for the algorithm. This method may return an
+        * empty collection, but may not return <code>null</code>.
+        * 
+        * @return A collection of configurable options.
+        */
+       public Collection<Option<?>> getOptions();
+
+
+       /**
+        * Initialize a new segmentation. This method is provided to
+        * allow algorithms to initialize any data structures needed
+        * for segmentation and to perform any pre-segmentation 
+        * necessary.
+        * 
+        * @param ctx
+        *          The segmentation context.
+        */
+       public void init(SegmentationContext ctx);
+
+
+       /**
+        * Do a full update of the segmentation based on the current context.
+        * 
+        * @param ctx
+        *          The segmentation context.
+        */
+       public void update(SegmentationContext ctx);
+
+
+       /**
+        * Perform an incremental update when a single annotation is added to the
+        * context. This method is provided for algorithms that can improve
+        * performance by only updating based on the last annotation change.
+        * 
+        * @param ctx
+        *          The segmentation context.
+        * @param a
+        *          The last annotation.
+        */
+       public void added(SegmentationContext ctx, Annotation a);
+
+
+       /**
+        * Perform an incremental update when a single annotation is removed from the
+        * context. This method is provided for algorithms that can improve
+        * performance by only updating based on the last annotation change.
+        * 
+        * @param ctx
+        *          The segmentation context.
+        * @param a
+        *          The removed annotation.
+        */
+       public void removed(SegmentationContext ctx, Annotation a);
+
+
+       /**
+        * Perform any operations required before moving on to the next segmentation
+        * context. This method is provided to allow algorithms to dispose of any
+        * internal data structures or resources.
+        * 
+        * @param ctx The segmentation context.
+        */
+       public void finish(SegmentationContext ctx);
+       
+       
+}
diff --git a/Annotation/src/ie/dcu/segment/annotate/Annotation.class b/Annotation/src/ie/dcu/segment/annotate/Annotation.class
new file mode 100644 (file)
index 0000000..240e257
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/annotate/Annotation.class differ
diff --git a/Annotation/src/ie/dcu/segment/annotate/Annotation.java b/Annotation/src/ie/dcu/segment/annotate/Annotation.java
new file mode 100644 (file)
index 0000000..b2fb899
--- /dev/null
@@ -0,0 +1,227 @@
+package ie.dcu.segment.annotate;
+
+import ie.dcu.swt.*;
+
+import java.util.*;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.*;
+
+/**
+ * Class encapsulating a single image annotation.
+ * 
+ * @author Kevin McGuinness
+ */
+public class Annotation {
+       private final AnnotationType type;
+       private final LinkedList<Point> points;
+       private Rectangle bounds;
+       private int lineWidth;
+       
+       /**
+        * Create an annotation of the given type.
+        * 
+        * @param type
+        *        The annotation type.
+        */
+       public Annotation(AnnotationType type) {
+               this(type, 1);
+       }
+       
+       /**
+        * Create an annotation of the given type and brush size.
+        * 
+        * @param type
+        *        The annotation type.
+        * @param width
+        *        The brush size.
+        */
+       public Annotation(AnnotationType type, int width) {
+               this (type, width, null);
+       }
+       
+       /**
+        * Create an annotation of the given type, brush size, and with
+        * the given initial point.
+        * 
+        * @param type
+        *        The annotation type.
+        * @param width
+        *        The brush size.
+        * @param pt
+        *        The initial point.
+        */
+       public Annotation(AnnotationType type, int width, Point pt) {
+               assert (type != null);
+               this.type = type;
+               points = new LinkedList<Point>();
+               setLineWidth(width);
+               
+               if (pt != null) {
+                       add(pt);
+               }
+       }
+       
+       
+       /**
+        * Set the annotation brush size.
+        * 
+        * @param width
+        *        The brush size (must be > 0).
+        */
+       public void setLineWidth(int width) {
+               assert (width > 0);
+               lineWidth = width;
+       }
+       
+       /**
+        * Get the annotation brush size.
+        */
+       public int getLineWidth() {
+               return lineWidth;
+       }
+       
+       /**
+        * Get the type of annotation.
+        */
+       public AnnotationType getType() {
+               return type;
+       }
+       
+       /**
+        * Add a point to the annotation.
+        * 
+        * @param pt
+        *        A point
+        */
+       public void add(Point pt) {
+               // Add point
+               points.add(pt);
+               
+               // Expand bounds
+               Rectangle m = new Rectangle(
+                               pt.x-1, pt.y-1, 3, 3
+               );
+               
+               if (bounds == null) {
+                       bounds = SwtUtils.clone(m);
+               } else {
+                       bounds.add(m);
+               }
+       }
+       
+       /**
+        * Returns the last point in the annotation, or <code>null</code> if the
+        * annotation has no points.
+        */
+       public Point last() {
+               return points.getLast();
+       }
+       
+       /**
+        * Returns the first point in the annotation, or <code>null</code> if the
+        * annotation has no points.
+        */
+       public Point first() {
+               return points.getFirst();
+       }
+       
+       /**
+        * Render the points onto an {@link ObservableImage} instance.
+        * 
+        * @param image
+        *        An {@link ObservableImage}.
+        */
+       public void paint(ObservableImage image) {
+               GC gc = image.beginPaint();
+               paint(gc, true);
+               image.endPaint(getBounds());
+       }
+       
+       /**
+        * Render the annotations onto an SWT image instance.
+        * 
+        * @param image
+        *        An image.
+        * @param antialias
+        *        Flag indicating whether antialiasing should be done.
+        */
+       public void paint(Image image, boolean antialias) {
+               GC gc = new GC(image);
+               paint(gc, antialias);
+               gc.dispose();
+       }
+       
+       /**
+        * Render the annotation onto the graphics context.
+        * 
+        * @param gc
+        *        A graphics context.
+        * @param antialias
+        *        Flag indicating whether antialiasing should be done.
+        */
+       public void paint(GC gc, boolean antialias) {
+               int npoints = points.size();
+               if (npoints == 0)       return;
+               
+               if (antialias) {
+                       gc.setAntialias(SWT.ON);
+               }
+               gc.setLineCap(SWT.CAP_ROUND);
+               gc.setLineJoin(SWT.JOIN_ROUND);
+               
+               gc.setLineWidth(lineWidth);
+               gc.setForeground(type.getColor());
+               
+               Point last = null;
+               
+               // Ensure single point or zero length lines are drawn
+               switch (npoints) {
+               case 1:
+               case 2:
+                       Point pt = points.get(0);
+                       last = new Point(pt.x+1, pt.y);
+               }
+               
+               // Draw points
+               for (Point p : points) {
+                       if (last != null) {
+                               gc.drawLine(last.x, last.y, p.x, p.y);
+                       }
+                       
+                       last = p;
+               }
+       }
+       
+       /**
+        * Returns a rectangle that encloses all pixels that this annotation
+        * represents. If the annotation is empty, returns <code>null</code>.
+        */
+       public Rectangle getBounds() {
+               if (bounds != null) {
+                       return new Rectangle(
+                                       bounds.x - lineWidth / 2, 
+                                       bounds.y - lineWidth / 2, 
+                                       bounds.width + lineWidth, 
+                                       bounds.height + lineWidth               
+                       );
+               }
+               
+               return null;
+       }
+       
+       
+       /**
+        * Returns an unmodifiable list of points for this annotation
+        */
+       public List<Point> points() {
+               return Collections.unmodifiableList(points);
+       }
+       
+       /**
+        * Returns the number of points in this annotation. 
+        */
+       public int count() {
+               return points.size();
+       }
+}
diff --git a/Annotation/src/ie/dcu/segment/annotate/AnnotationAdapter.class b/Annotation/src/ie/dcu/segment/annotate/AnnotationAdapter.class
new file mode 100644 (file)
index 0000000..367219d
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/annotate/AnnotationAdapter.class differ
diff --git a/Annotation/src/ie/dcu/segment/annotate/AnnotationAdapter.java b/Annotation/src/ie/dcu/segment/annotate/AnnotationAdapter.java
new file mode 100644 (file)
index 0000000..8ef6cec
--- /dev/null
@@ -0,0 +1,46 @@
+package ie.dcu.segment.annotate;
+
+/**
+ * Class to simplify implementation of annotation listeners. For use when the
+ * listener is only interested in changes in the generic sense.
+ * 
+ * @see AnnotationListener
+ * @author Kevin McGuinness
+ */
+public abstract class AnnotationAdapter implements AnnotationListener {
+
+       /**
+        * Forwards call to {@link #annotationsChanged(AnnotationEvent)}
+        */
+       public void annotationPerformed(AnnotationEvent e) {
+               annotationsChanged(e);
+       }
+       
+       /**
+        * Forwards call to {@link #annotationsChanged(AnnotationEvent)}
+        */
+       public void annotationRedone(AnnotationEvent e) {
+               annotationsChanged(e);
+       }
+
+       /**
+        * Forwards call to {@link #annotationsChanged(AnnotationEvent)}
+        */
+       public void annotationUndone(AnnotationEvent e) {
+               annotationsChanged(e);
+       }
+
+       /**
+        * Forwards call to {@link #annotationsChanged(AnnotationEvent)}
+        */
+       public void annotationsCleared(AnnotationEvent e) {
+               annotationsChanged(e);
+       }
+       
+       /**
+        * Called when any changes to the annotations occur.
+        * 
+        * @param e The {@link AnnotationEvent} object.
+        */
+       public abstract void annotationsChanged(AnnotationEvent e);
+}
diff --git a/Annotation/src/ie/dcu/segment/annotate/AnnotationEvent$Type.class b/Annotation/src/ie/dcu/segment/annotate/AnnotationEvent$Type.class
new file mode 100644 (file)
index 0000000..98491b9
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/annotate/AnnotationEvent$Type.class differ
diff --git a/Annotation/src/ie/dcu/segment/annotate/AnnotationEvent.class b/Annotation/src/ie/dcu/segment/annotate/AnnotationEvent.class
new file mode 100644 (file)
index 0000000..432395e
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/annotate/AnnotationEvent.class differ
diff --git a/Annotation/src/ie/dcu/segment/annotate/AnnotationEvent.java b/Annotation/src/ie/dcu/segment/annotate/AnnotationEvent.java
new file mode 100644 (file)
index 0000000..f189c38
--- /dev/null
@@ -0,0 +1,34 @@
+package ie.dcu.segment.annotate;
+
+/**
+ * Annotation event class
+ * 
+ * @see AnnotationListener
+ * @author Kevin McGuinness
+ */
+public class AnnotationEvent {
+       public final AnnotationManager manager;
+       public final Annotation annotation;
+       public final Type type;
+       
+       
+       public AnnotationEvent(
+                       AnnotationManager manager, 
+                       Annotation annotation, 
+                       Type type
+       ) {
+               this.manager = manager;
+               this.annotation = annotation;
+               this.type = type;
+       }
+       
+       /**
+        * Event type
+        */
+       public enum Type {
+               Undone, 
+               Redone,
+               Added,
+               Cleared
+       }
+}
diff --git a/Annotation/src/ie/dcu/segment/annotate/AnnotationListener.class b/Annotation/src/ie/dcu/segment/annotate/AnnotationListener.class
new file mode 100644 (file)
index 0000000..cb1ee74
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/annotate/AnnotationListener.class differ
diff --git a/Annotation/src/ie/dcu/segment/annotate/AnnotationListener.java b/Annotation/src/ie/dcu/segment/annotate/AnnotationListener.java
new file mode 100644 (file)
index 0000000..7de779b
--- /dev/null
@@ -0,0 +1,14 @@
+package ie.dcu.segment.annotate;
+
+/**
+ * Interface for classes interested in annotation events.
+ * 
+ * @see AnnotationEvent
+ * @author Kevin McGuinness
+ */
+public interface AnnotationListener {
+       public void annotationPerformed(AnnotationEvent e);
+       public void annotationUndone(AnnotationEvent e);
+       public void annotationRedone(AnnotationEvent e);
+       public void annotationsCleared(AnnotationEvent e);
+}
diff --git a/Annotation/src/ie/dcu/segment/annotate/AnnotationManager.class b/Annotation/src/ie/dcu/segment/annotate/AnnotationManager.class
new file mode 100644 (file)
index 0000000..6f7c1e8
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/annotate/AnnotationManager.class differ
diff --git a/Annotation/src/ie/dcu/segment/annotate/AnnotationManager.java b/Annotation/src/ie/dcu/segment/annotate/AnnotationManager.java
new file mode 100644 (file)
index 0000000..7ea886d
--- /dev/null
@@ -0,0 +1,323 @@
+package ie.dcu.segment.annotate;
+
+import ie.dcu.swt.ObservableImage;
+
+import java.io.*;
+import java.util.*;
+
+import org.eclipse.swt.graphics.*;
+
+/**
+ * Class that manages a set of image annotations.
+ *  
+ * @author Kevin McGuinness
+ */
+public class AnnotationManager {
+       private static final String FILE_TAG = "Annotations";
+       private final LinkedList<Annotation> annotations;
+       private final LinkedList<Annotation> redos;
+       private final List<AnnotationListener> listeners;
+       
+       public AnnotationManager() {
+               annotations = new LinkedList<Annotation>();
+               redos = new LinkedList<Annotation>();
+               listeners = new ArrayList<AnnotationListener>(2);
+       }
+       
+       
+       public void add(Annotation a) {
+               annotations.addLast(a);
+               redos.clear();
+               fireAnnotationPerformed(a);
+       }
+       
+       
+       public boolean canUndo() {
+               return !annotations.isEmpty();
+       }
+       
+       
+       public boolean canRedo() {
+               return !redos.isEmpty();
+       }
+       
+       
+       public void undo() {
+               if (canUndo()) {
+                       Annotation a = annotations.removeLast();
+                       redos.addFirst(a);
+                       fireAnnotationUndone(a);
+               }
+       }
+       
+       
+       public void redo() {
+               if (canRedo()) {
+                       Annotation a = redos.removeFirst();
+                       annotations.addLast(a);
+                       fireAnnotationRedone(a);
+               }
+       }
+       
+       
+       public void clear() {
+               if (annotations.size() > 0) {
+                       annotations.clear();
+                       redos.clear();
+                       fireAnnotationsCleared();
+               }
+       }
+       
+       
+       public Annotation getUndoable() {
+               if (!canUndo()) {
+                       return null;
+               }
+               return annotations.getLast();
+       }
+       
+       
+       public Annotation getRedoable() {
+               if (!canRedo()) {
+                       return null;
+               }
+               return redos.getFirst();
+       }
+       
+       
+       public Annotation last() {
+               if (!annotations.isEmpty()) {
+                       return annotations.getLast();
+               }
+               return null;
+       }
+       
+       
+       public List<Annotation> annotations() {
+               return Collections.unmodifiableList(annotations);
+       }
+       
+       
+       public int count() {
+               return annotations.size();
+       }
+       
+       
+       public int countForeground() {
+               int count = 0;
+               for (Annotation a : annotations) {
+                       if (a.getType() == AnnotationType.Foreground) {
+                               count++;
+                       }
+               }
+               return count;
+       }
+       
+       
+       public int countBackground() {
+               int count = 0;
+               for (Annotation a : annotations) {
+                       if (a.getType() == AnnotationType.Background) {
+                               count++;
+                       }
+               }
+               return count;
+       }
+       
+       
+       public boolean hasForegroundAnnotation() {
+               for (Annotation a : annotations) {
+                       if (a.getType() == AnnotationType.Foreground) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+       
+       
+       public boolean hasBackgroundAnnotation() {
+               for (Annotation a : annotations) {
+                       if (a.getType() == AnnotationType.Background) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+       
+       
+       public void paint(ObservableImage image) {
+               for (Annotation a : annotations) {
+                       a.paint(image);
+               }
+       }
+       
+       
+       public void paint(GC gc, boolean antialias) {
+               for (Annotation a : annotations) {
+                       a.paint(gc, antialias);
+               }
+       }
+       
+       
+       public void paint(Image image, boolean antialias) {
+               for (Annotation a : annotations) {
+                       a.paint(image, antialias);
+               }
+       }
+       
+       
+       public Rectangle getBounds() {
+               Rectangle rect = new Rectangle(0,0,0,0);
+               for (Annotation a : annotations) {
+                       rect.add(a.getBounds());
+               }
+               return rect;
+       }
+       
+       
+       public void addAnnotationListener(AnnotationListener listener) {
+               listeners.add(listener);
+       }
+       
+       
+       public void removeAnnotationListener(AnnotationListener listener) {
+               listeners.remove(listener);
+       }
+       
+       
+       private void fireAnnotationsCleared() {
+               AnnotationEvent e = null;
+               for (AnnotationListener listener : listeners) {
+                       if (e == null) {
+                               e = new AnnotationEvent(this, null, AnnotationEvent.Type.Cleared);
+                       }
+                       listener.annotationsCleared(e);
+               }
+       }
+
+
+       private void fireAnnotationPerformed(Annotation a) {
+               AnnotationEvent e = null;
+               for (AnnotationListener listener : listeners) {
+                       if (e == null) {
+                               e = new AnnotationEvent(this, a, AnnotationEvent.Type.Added);
+                       }
+                       listener.annotationPerformed(e);
+               }
+       }
+       
+       
+       private void fireAnnotationUndone(Annotation a) {
+               AnnotationEvent e = null;
+               for (AnnotationListener listener : listeners) {
+                       if (e == null) {
+                               e = new AnnotationEvent(this, a, AnnotationEvent.Type.Undone);
+                       }
+                       listener.annotationUndone(e);
+               }
+       }
+       
+       
+       private void fireAnnotationRedone(Annotation a) {
+               AnnotationEvent e = null;
+               for (AnnotationListener listener : listeners) {
+                       if (e == null) {
+                               e = new AnnotationEvent(this, a, AnnotationEvent.Type.Redone);
+                       }
+                       listener.annotationRedone(e);
+               }
+       }
+       
+       
+       public void save(File file) throws IOException {
+               FileOutputStream out = new FileOutputStream(file);
+               
+               try {
+                       save(out);
+               } finally {
+                       out.close();
+               }
+       }
+       
+       public void save(OutputStream o) throws IOException {
+               
+               DataOutputStream out = new DataOutputStream(
+                               new BufferedOutputStream(o));
+               
+               // Write tag and count
+               out.writeUTF(FILE_TAG);
+               out.writeInt(annotations.size());
+               
+               for (Annotation a : annotations) {
+                       
+                       // Write parameters
+                       out.writeInt(a.getType().ordinal());
+                       out.writeInt(a.getLineWidth());
+                       out.writeInt(a.points().size());
+                       
+                       // Write points
+                       for (Point p : a.points()) {
+                               out.writeInt(p.x);
+                               out.writeInt(p.y);
+                       }
+               }
+               
+               // Flush
+               out.flush();
+       }
+       
+       public void load(File file) throws IOException {
+               
+               FileInputStream in = new FileInputStream(file);
+               
+               try {
+                       load(in);       
+               } finally {
+                       in.close();
+               }       
+       }
+       
+       public void load(InputStream is) throws IOException {
+               
+               // In case container is being reused, clear old data first
+               annotations.clear();
+               redos.clear();
+               
+               // Create and buffer data input stream
+               DataInputStream in = new DataInputStream(
+                               new BufferedInputStream(is)
+               );
+                       
+               // Check tag
+               String tag = in.readUTF();
+               if (!tag.equals(FILE_TAG)) {
+                       throw new IOException("Unrecognized file format");
+               }
+               
+               // Read annotations
+               int n = in.readInt();
+               for (int i = 0; i < n; i++) {
+                       
+                       // Read parameters
+                       int typeid = in.readInt();
+                       int lineWidth = in.readInt();
+                       int npoints = in.readInt();
+                       
+                       
+                       // Create annotation
+                       AnnotationType type = AnnotationType.valueOf(typeid);
+                       Annotation a = new Annotation(type, lineWidth);
+                       
+                       
+                       // Read points
+                       for (int j = 0; j < npoints; j++) {
+                               int x = in.readInt();
+                               int y = in.readInt();
+                               a.add(new Point(x, y));
+                       }
+                       
+                       //Add annotation
+                       add(a);
+               }
+       }
+}
diff --git a/Annotation/src/ie/dcu/segment/annotate/AnnotationType$1.class b/Annotation/src/ie/dcu/segment/annotate/AnnotationType$1.class
new file mode 100644 (file)
index 0000000..35f2b63
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/annotate/AnnotationType$1.class differ
diff --git a/Annotation/src/ie/dcu/segment/annotate/AnnotationType.class b/Annotation/src/ie/dcu/segment/annotate/AnnotationType.class
new file mode 100644 (file)
index 0000000..ae636a4
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/annotate/AnnotationType.class differ
diff --git a/Annotation/src/ie/dcu/segment/annotate/AnnotationType.java b/Annotation/src/ie/dcu/segment/annotate/AnnotationType.java
new file mode 100644 (file)
index 0000000..0eb7b64
--- /dev/null
@@ -0,0 +1,133 @@
+package ie.dcu.segment.annotate;
+
+import org.eclipse.jface.resource.*;
+import org.eclipse.jface.util.*;
+import org.eclipse.swt.graphics.*;
+
+/**
+ * Annotation type enumeration.
+ * 
+ * The color of the foreground/background brushes is stored in the JFace
+ * ColorRegistry using the {@link #key} value to generate the key. If changed
+ * the {@link #getColor()} method will return the new color. will return the new
+ * color.
+ * 
+ * @author Kevin McGuinness
+ * 
+ */
+public enum AnnotationType implements IPropertyChangeListener {
+       // Ordinal used for serialization, don't change order
+       Foreground, 
+       Background;
+
+               
+       /**
+        * Default foreground color.
+        */
+       public static final RGB DEFAULT_FOREGROUND = new RGB(255,0,0);
+       
+       
+       /**
+        * Default background color.
+        */
+       public static final RGB DEFAULT_BACKGROUND = new RGB(0,0,255);
+
+       
+       /**
+        * Annotation color registry key.
+        */
+       public final String key;
+       
+
+       /**
+        * Annotation brush color.
+        */
+       private Color color;
+       
+       
+       /**
+        * Initializer
+        */
+       private AnnotationType() {
+               key = String.format("%s#%s", getClass().getName(), name());
+       }
+
+
+       /**
+        * Get the color of the annotation brush.
+        * 
+        * @return The annotation brush color.
+        */
+       public Color getColor() {
+               if (color == null) {
+                       
+                       // Get registry
+                       ColorRegistry cr = JFaceResources.getColorRegistry();
+                       
+                       
+                       // Set default
+                       if (!cr.hasValueFor(key)) {
+                               switch (this) {
+                               case Foreground:
+                                       cr.put(key, DEFAULT_FOREGROUND);
+                                       break;
+                               default:
+                                       cr.put(key, DEFAULT_BACKGROUND);
+                               }
+                       }
+                       
+                       cr.addListener(this);
+                       
+                       // Get color
+                       color = cr.get(key);
+               }
+               
+               return color;
+       }
+
+
+       /**
+        * Returns the annotation type, inverted.
+        * 
+        * @return The opposite annotation type.
+        */
+       public AnnotationType invert() {
+               switch (this) {
+               case Foreground:
+                       return Background;
+               case Background:
+                       return Foreground;
+               }
+               throw new Error();
+       }
+
+
+       /**
+        * Returns the annotation type corresponding to the given ordinal.
+        * 
+        * @param ordinal
+        *          The ordinal.
+        * @return The annotation type.
+        * @throws IllegalArgumentException
+        *           If the given ordinal value is out of range.
+        */
+       public static AnnotationType valueOf(int ordinal) throws IllegalArgumentException {
+               AnnotationType[] values = values();
+               if (ordinal < 0 || ordinal >= values.length) {
+                       throw new IllegalArgumentException("No such ordinal value: " + ordinal);
+               }
+               return values[ordinal];
+       }
+       
+
+       /**
+        * Listen for changes in the color registry
+        */
+       public void propertyChange(PropertyChangeEvent e) {
+               if (e.getProperty().equals(key)) {
+                       JFaceResources.getColorRegistry().removeListener(this);
+                       // Flag property needs reloading
+                       color = null;
+               }               
+       }
+}
diff --git a/Annotation/src/ie/dcu/segment/options/AbstractEditor.class b/Annotation/src/ie/dcu/segment/options/AbstractEditor.class
new file mode 100644 (file)
index 0000000..1ae9eab
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/options/AbstractEditor.class differ
diff --git a/Annotation/src/ie/dcu/segment/options/AbstractOption.class b/Annotation/src/ie/dcu/segment/options/AbstractOption.class
new file mode 100644 (file)
index 0000000..0b64157
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/options/AbstractOption.class differ
diff --git a/Annotation/src/ie/dcu/segment/options/AbstractOption.java b/Annotation/src/ie/dcu/segment/options/AbstractOption.java
new file mode 100644 (file)
index 0000000..da9dd2a
--- /dev/null
@@ -0,0 +1,91 @@
+package ie.dcu.segment.options;
+
+/**
+ * Abstract implementation of the {@link Option} interface.
+ * 
+ * @author Kevin McGuinness
+ */
+public abstract class AbstractOption<T> implements Option<T> {
+       private final OptionType type;
+       private final String name;
+       private final String description;
+       private final T defaultValue;
+       private T value;
+
+
+       protected AbstractOption(
+                       OptionType type, String name, String description, T defaultValue) {
+               
+               // Preconditions
+               assert (type != null);
+               assert (name != null);
+               assert (description != null);
+               assert (defaultValue != null);
+               
+               // Assign
+               this.type = type;
+               this.name = name;
+               this.description = description;
+               this.defaultValue = defaultValue;
+               this.value = defaultValue;
+       }
+
+
+       public OptionType getType() {
+               return type;
+       }
+
+
+       public String getName() {
+               return name;
+       }
+
+
+       public String getDescription() {
+               return description;
+       }
+
+
+       public T getDefaultValue() {
+               return defaultValue;
+       }
+
+
+       public T getValue() {
+               return value;
+       }
+
+
+       public void setValue(Object value) {
+               if (value == null) {
+                       this.value = defaultValue;
+               } else {
+                       Conversion<T> conv = convert(value);
+                       if (conv.isOk()) {
+                               this.value = conv.getResult();
+                       } else {
+                               this.value = defaultValue;
+                       }
+               }
+       }
+
+
+       public T[] values() {
+               return null;
+       }
+
+
+       protected Conversion<T> valid(T result) {
+               return new Conversion<T>(result, null);
+       }
+
+
+       protected Conversion<T> invalid(String message) {
+               return new Conversion<T>(null, message);
+       }
+
+
+       protected Conversion<T> invalid(String format, Object... args) {
+               return new Conversion<T>(null, String.format(format, args));
+       }
+}
diff --git a/Annotation/src/ie/dcu/segment/options/ComboEditor.class b/Annotation/src/ie/dcu/segment/options/ComboEditor.class
new file mode 100644 (file)
index 0000000..513d573
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/options/ComboEditor.class differ
diff --git a/Annotation/src/ie/dcu/segment/options/Conversion.class b/Annotation/src/ie/dcu/segment/options/Conversion.class
new file mode 100644 (file)
index 0000000..48e0a23
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/options/Conversion.class differ
diff --git a/Annotation/src/ie/dcu/segment/options/Conversion.java b/Annotation/src/ie/dcu/segment/options/Conversion.java
new file mode 100644 (file)
index 0000000..468f167
--- /dev/null
@@ -0,0 +1,54 @@
+package ie.dcu.segment.options;
+
+/**
+ * The result of an attempted conversion.
+ * 
+ * @author Kevin McGuinness
+ */
+public class Conversion<T> {
+       private final String message;
+       private final T result;
+
+       /**
+        * Create a conversion object with the given message and result. The message
+        * should be null if the conversion was valid.
+        * 
+        * @param result
+        *        The result, or <code>null</code>.
+        * @param message
+        *        A message, or <code>null</code>.
+        */
+       public Conversion(T result, String message) {
+               this.message = message;
+               this.result = result;
+       }
+
+       /**
+        * Returns <code>true</code> of the conversion went OK.
+        */
+       public boolean isOk() {
+               return message == null;
+       }
+
+       /**
+        * Returns an error message if the conversion failed.
+        */
+       public String getMessage() {
+               return message;
+       }
+
+       /**
+        * Returns the result of the conversion if it succeeded.
+        */
+       public T getResult() {
+               return result;
+       }
+
+       public String toString() {
+               if (isOk()) {
+                       return String.format("Conversion [ value = %s ]", result);
+               } else {
+                       return String.format("Conversion [ error = %s ]", message);
+               }
+       }
+}
diff --git a/Annotation/src/ie/dcu/segment/options/ConversionListener.class b/Annotation/src/ie/dcu/segment/options/ConversionListener.class
new file mode 100644 (file)
index 0000000..31ff855
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/options/ConversionListener.class differ
diff --git a/Annotation/src/ie/dcu/segment/options/DecimalOption.class b/Annotation/src/ie/dcu/segment/options/DecimalOption.class
new file mode 100644 (file)
index 0000000..c41c985
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/options/DecimalOption.class differ
diff --git a/Annotation/src/ie/dcu/segment/options/DecimalOption.java b/Annotation/src/ie/dcu/segment/options/DecimalOption.java
new file mode 100644 (file)
index 0000000..649e6cc
--- /dev/null
@@ -0,0 +1,76 @@
+package ie.dcu.segment.options;
+
+/**
+ * A decimal (floating point) segmentation algorithm parameter.
+ * 
+ * @author Kevin McGuinness
+ */
+public class DecimalOption extends AbstractOption<Double> {
+       private final double min;
+       private final double max;
+
+       
+       /**
+        * Create a decimal option with the given name, description, and default
+        * value.
+        * 
+        * @param name
+        *        The option name
+        * @param description
+        *        A description of the option
+        * @param def
+        *        The default value for the option
+        */
+       public DecimalOption(String name, String description, double def) {
+               this(name, description, def, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);
+       }
+       
+       /**
+        * Create a decimal option with the given name, description, default
+        * value, minimum allowable value, and maximum allowable value.
+        * 
+        * @param name
+        *        The option name
+        * @param description
+        *        A description of the option
+        * @param def
+        *        The default value for the option
+        * @param min
+        *        The minimum allowable value for the option
+        * @param max
+        *        The maximum allowable value for the option
+        */
+       public DecimalOption(String name, String description, double def, double min, double max) {
+               super(OptionType.Decimal, name, description, def);
+               this.min = min;
+               this.max = max;
+       }
+
+       public Conversion<Double> convert(Object value) {
+               if (value instanceof Double) {
+                       return valid((Double) value);
+               } else if (value != null) {
+                       try {
+                               return checkRange(new Double(value.toString().trim()));
+                       } catch (NumberFormatException e) {
+                               // Invalid
+                               String mesg = e.getLocalizedMessage();
+                               return invalid("%s is not an decimal number: %s", getName(), mesg);
+                       }
+               }
+               return invalid("value is null");
+       }
+       
+       
+       private Conversion<Double> checkRange(double val) {
+               if (val >= min && val <= max) {
+                       // OK
+                       return valid(val);
+                       
+               } 
+               
+               // Out of range
+               String format = "%s must be in ther range (%f, %f), value is %f";
+               return invalid(format, getName(), min, max, val);
+       }
+}
diff --git a/Annotation/src/ie/dcu/segment/options/EnumOption.class b/Annotation/src/ie/dcu/segment/options/EnumOption.class
new file mode 100644 (file)
index 0000000..5462be7
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/options/EnumOption.class differ
diff --git a/Annotation/src/ie/dcu/segment/options/EnumOption.java b/Annotation/src/ie/dcu/segment/options/EnumOption.java
new file mode 100644 (file)
index 0000000..11ced43
--- /dev/null
@@ -0,0 +1,65 @@
+package ie.dcu.segment.options;
+
+/**
+ * A segmentation algorithm parameter that can assume one of a set of predefined
+ * values.
+ * 
+ * @author Kevin McGuinness
+ */
+public class EnumOption<T extends Enum<T>> extends AbstractOption<T> {
+       private Class<T> clazz;
+
+
+       /**
+        * Create an enum option.
+        * 
+        * @param clazz
+        *        The class of the enum.
+        * @param name
+        *        The option name.
+        * @param description
+        *        The option description.
+        * @param def
+        *        The default value.
+        */
+       public EnumOption(Class<T> clazz, String name, String description, T def) {
+               super(OptionType.Enumeration, name, description, def);
+               this.clazz = clazz;
+       }
+
+
+       public T[] values() {
+               return clazz.getEnumConstants();
+       }
+
+
+       public Conversion<T> convert(Object value) {
+               if (clazz.isInstance(value)) {
+                       return valid(clazz.cast(value));
+               } else if (value != null) {
+                       
+                       String str = value.toString().trim();
+                       Conversion<T> conv;
+                       try {
+                               conv = valid(Enum.valueOf(clazz, str));
+                       } catch (IllegalArgumentException e) {
+                               conv = invalid("Invalid value \"%s\" for %s", value, getName());
+                       }
+                       
+                       if (!conv.isOk()) {
+                               // Try convert from an integer
+                               try {
+                                       int x = Integer.parseInt(str);
+                                       T[] v = values();
+                                       if (x > 0 && x < v.length) {
+                                               return valid(v[x]);
+                                       }
+                                       
+                               } catch (NumberFormatException e) {
+                                       // Ignore .. we already have an error message from the string conversion
+                               }
+                       }
+               }
+               return invalid("%s is null", getName());
+       }
+}
diff --git a/Annotation/src/ie/dcu/segment/options/IntegerOption.class b/Annotation/src/ie/dcu/segment/options/IntegerOption.class
new file mode 100644 (file)
index 0000000..0f09407
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/options/IntegerOption.class differ
diff --git a/Annotation/src/ie/dcu/segment/options/IntegerOption.java b/Annotation/src/ie/dcu/segment/options/IntegerOption.java
new file mode 100644 (file)
index 0000000..c9f62b0
--- /dev/null
@@ -0,0 +1,79 @@
+package ie.dcu.segment.options;
+
+/**
+ * An integer segmentation algorithm parameter.
+ * 
+ * @author Kevin McGuinness
+ */
+public class IntegerOption extends AbstractOption<Integer> {
+       private final int min;
+       private final int max;
+
+
+       /**
+        * Create ain integer option with the given name, description, and default
+        * value.
+        * 
+        * @param name
+        *        The option name
+        * @param description
+        *        A description of the option
+        * @param def
+        *        The default value for the option
+        */
+       public IntegerOption(String name, String description, int def) {
+               this(name, description, def, Integer.MIN_VALUE, Integer.MAX_VALUE);
+       }
+
+
+       /**
+        * Create an integer option with the given name, description, default
+        * value, minimum allowable value, and maximum allowable value.
+        * 
+        * @param name
+        *        The option name
+        * @param description
+        *        A description of the option
+        * @param def
+        *        The default value for the option
+        * @param min
+        *        The minimum allowable value for the option
+        * @param max
+        *        The maximum allowable value for the option
+        */
+       public IntegerOption(String name, String description, int def, int min, int max) {
+               super(OptionType.Integer, name, description, def);
+               this.min = min;
+               this.max = max;
+       }
+
+
+       public Conversion<Integer> convert(Object value) {
+               if (value instanceof Integer) {
+                       return checkRange((Integer) value);
+               } else if (value != null) {
+                       
+                       try {
+                               return checkRange(new Integer(value.toString().trim()));
+                       } catch (NumberFormatException e) {
+                               // Invalid
+                               String mesg = e.getLocalizedMessage();
+                               return invalid("%s is not an integer: %s", getName(), mesg);
+                       }
+               }
+               return invalid("%s is null", getName());
+       }
+       
+       
+       private Conversion<Integer> checkRange(int val) {
+               if (val >= min && val <= max) {
+                       // OK
+                       return valid(val);
+                       
+               } 
+               
+               // Out of range
+               String format = "%s must be in ther range (%d, %d), value is %d";
+               return invalid(format, getName(), min, max, val);
+       }
+}
diff --git a/Annotation/src/ie/dcu/segment/options/Option.class b/Annotation/src/ie/dcu/segment/options/Option.class
new file mode 100644 (file)
index 0000000..6850177
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/options/Option.class differ
diff --git a/Annotation/src/ie/dcu/segment/options/Option.java b/Annotation/src/ie/dcu/segment/options/Option.java
new file mode 100644 (file)
index 0000000..4778356
--- /dev/null
@@ -0,0 +1,57 @@
+package ie.dcu.segment.options;
+
+/**
+ * Interface for a segmentation algorithm parameter.
+ * 
+ * @author Kevin McGuinness
+ */
+public interface Option<T> {
+       
+       /**
+        * Return the option type
+        */
+       public OptionType getType();
+       
+       /**
+        * Try to convert a object to the required type for the option.
+        * 
+        * @param value
+        *        An object.
+        * @return A conversion object containing the result or an error message.
+        */
+       public Conversion<T> convert(Object value);
+       
+       /**
+        * Set the option to the given object value.
+        * 
+        * @param value
+        *        A value.
+        */
+       public void setValue(Object value);
+       
+       /**
+        * Get the current value.
+        */
+       public T getValue();
+       
+       /**
+        * Get the default option value.
+        */
+       public T getDefaultValue();
+       
+       /**
+        * Returns all allowable values, or <code>null</code>.
+        */
+       public T[] values();
+       
+       /**
+        * Return the option name.
+        */
+       public String getName();
+       
+       /**
+        * Return a description of the option
+        */
+       public String getDescription();
+}
+
diff --git a/Annotation/src/ie/dcu/segment/options/OptionEditor.class b/Annotation/src/ie/dcu/segment/options/OptionEditor.class
new file mode 100644 (file)
index 0000000..8aa1462
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/options/OptionEditor.class differ
diff --git a/Annotation/src/ie/dcu/segment/options/OptionType.class b/Annotation/src/ie/dcu/segment/options/OptionType.class
new file mode 100644 (file)
index 0000000..c156f76
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/options/OptionType.class differ
diff --git a/Annotation/src/ie/dcu/segment/options/OptionType.java b/Annotation/src/ie/dcu/segment/options/OptionType.java
new file mode 100644 (file)
index 0000000..a05daef
--- /dev/null
@@ -0,0 +1,44 @@
+package ie.dcu.segment.options;
+
+/**
+ * Enumeration of segmentation algorithm parameter types.
+ * 
+ * @author Kevin McGuinness
+ */
+public enum OptionType {
+       
+       /**
+        * A textual (string) option.
+        * 
+        * @see TextOption
+        */
+       Text,
+       
+       /**
+        * An integer option
+        * 
+        * @see IntegerOption
+        */
+       Integer,
+       
+       /**
+        * A decimal option
+        * 
+        * @see DecimalOption
+        */
+       Decimal,
+       
+       /**
+        * A toggle option
+        * 
+        * @see ToggleOption
+        */
+       Toggle,
+       
+       /**
+        * An enumerative option
+        * 
+        * @see EnumOption
+        */
+       Enumeration;
+}
diff --git a/Annotation/src/ie/dcu/segment/options/SegmenterOptionDialog$1.class b/Annotation/src/ie/dcu/segment/options/SegmenterOptionDialog$1.class
new file mode 100644 (file)
index 0000000..f64a4c3
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/options/SegmenterOptionDialog$1.class differ
diff --git a/Annotation/src/ie/dcu/segment/options/SegmenterOptionDialog$StatusListener.class b/Annotation/src/ie/dcu/segment/options/SegmenterOptionDialog$StatusListener.class
new file mode 100644 (file)
index 0000000..3300b95
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/options/SegmenterOptionDialog$StatusListener.class differ
diff --git a/Annotation/src/ie/dcu/segment/options/SegmenterOptionDialog.class b/Annotation/src/ie/dcu/segment/options/SegmenterOptionDialog.class
new file mode 100644 (file)
index 0000000..2fe0abd
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/options/SegmenterOptionDialog.class differ
diff --git a/Annotation/src/ie/dcu/segment/options/SegmenterOptionDialog.java b/Annotation/src/ie/dcu/segment/options/SegmenterOptionDialog.java
new file mode 100644 (file)
index 0000000..92a65e4
--- /dev/null
@@ -0,0 +1,383 @@
+package ie.dcu.segment.options;
+
+import ie.dcu.segment.Segmenter;
+
+import java.util.*;
+import java.util.List;
+
+import org.eclipse.jface.dialogs.*;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.ScrolledComposite;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+
+/**
+ * Dynamically builds a dialog box for the segmentation algorithms options.
+ * 
+ * @author Kevin McGuinness
+ */
+public class SegmenterOptionDialog extends TitleAreaDialog {
+       private final List<OptionEditor> editors;
+       private final Segmenter segmenter;
+
+       
+       public SegmenterOptionDialog(Shell parent, Segmenter segmenter) {
+               super(parent);
+               
+               // Setup final fields
+               this.editors = new LinkedList<OptionEditor>();
+               this.segmenter = segmenter;
+               
+               // Make it resizable
+               setShellStyle(getShellStyle() | SWT.RESIZE);
+       }
+       
+       
+       @Override
+       protected void okPressed() {
+               // Apply changes
+               for (OptionEditor editor : editors) {
+                       editor.apply();
+               }
+               
+               // Close
+               super.okPressed();
+       }
+
+
+       @Override
+       protected Control createContents(Composite parent) {
+               Control contents = super.createContents(parent);
+               
+               // Set dialog title
+               getShell().setText("Segmenter Options");
+               
+               // Set title area title
+               setTitle("Configure Segmenter Options");
+               
+               // Set message
+               setMessage(String.format("Configure parameters for %s", 
+                               segmenter.getName()));
+               
+               // Done
+               return contents;
+       }
+
+       
+       @Override
+       protected Control createDialogArea(Composite parent) {
+               Composite composite = (Composite) super.createDialogArea(parent);
+               
+               // Create scrolled area
+               ScrolledComposite scroller = new ScrolledComposite(composite, 
+                               SWT.H_SCROLL | SWT.V_SCROLL);
+               
+               // Configure scrolled area
+               scroller.setLayoutData(new GridData(GridData.FILL_BOTH));
+               scroller.setExpandHorizontal(true);
+               scroller.setExpandVertical(true);
+               scroller.setAlwaysShowScrollBars(false);
+               
+               // Create content
+               Composite content = new Composite(scroller, SWT.NONE);
+
+               // Create content layout
+               GridLayout layout = new GridLayout();
+               layout.marginTop  = layout.marginBottom = 10;
+               layout.marginLeft = layout.marginRight = 5;
+               layout.numColumns = 2;
+               content.setLayout(layout);
+               
+               // Create listener
+               StatusListener listener = new StatusListener();
+               
+               // Add options
+               for (Option<?> opt : segmenter.getOptions()) {
+                       
+                       // Create option label
+                       Label label = new Label(content, SWT.NONE);
+                       label.setText(opt.getName());
+                       label.setToolTipText(opt.getDescription());
+                       
+                       // Create editor layout
+                       GridData data = new GridData();
+                       data.horizontalIndent = 25;
+                       data.grabExcessHorizontalSpace = true;
+                       data.horizontalAlignment = SWT.FILL;
+                       
+                       // Create editor
+                       OptionEditor editor = createEditor(content, opt);
+                       editor.getControl().setLayoutData(data);
+                       editor.addConversionListener(listener);
+               }
+               
+               // Set scroll area content
+               scroller.setContent(content);
+               
+               // Compute scroll area min size
+               scroller.setMinSize(content.computeSize(
+                               SWT.DEFAULT, SWT.DEFAULT)
+               );
+               
+               // Done
+               return composite;
+       }
+
+       
+       @Override
+       protected Point getInitialSize() {
+               return new Point(450,350);
+       }       
+       
+       
+       public OptionEditor createEditor(Composite parent, Option<?> option) {
+               OptionEditor editor;
+               
+               // Use an combo editor for enums, otherwise use a text editor
+               switch (option.getType()) {
+               case Enumeration:
+                       editor = new ComboEditor(parent, option);
+                       break;
+               case Toggle:
+                       editor = new ToggleEditor(parent, option);
+                       break;
+               default:
+                       editor = new TextEditor(parent, option);
+               }
+               
+               editors.add(editor);
+               return editor;
+       }
+
+
+       /**
+        * Updates error message and OK button status when a conversion occurs.
+        * 
+        * @param conversion
+        *          The conversion.
+        */
+       private void handleConversion(Conversion<?> conversion) {
+               boolean ok = false;
+               
+               if (conversion.isOk()) {
+                       // Check all others
+                       Conversion<?> conv = null;
+                       for (OptionEditor editor : editors) {
+                               Conversion<?> current = editor.convert();
+                               if (!current.isOk()) {
+                                       conv = current;
+                                       break;
+                               }
+                       }
+                       if (conv == null) {
+                               setErrorMessage(null);
+                               ok = true;
+                       } else {
+                               setErrorMessage(conv.getMessage());
+                       }
+               } else {
+                       
+                       setErrorMessage(conversion.getMessage());
+               }
+               
+               getButton(IDialogConstants.OK_ID).setEnabled(ok);
+       }
+
+
+       /**
+        * Updates error message when edits and focus changes occur.
+        */
+       private final class StatusListener implements ConversionListener {
+               public void conversionPerformed(Conversion<?> conversion) {
+                       handleConversion(conversion);
+               }
+       }
+}
+
+
+
+
+interface ConversionListener {
+       public void conversionPerformed(Conversion<?> conversion);
+}
+
+
+interface OptionEditor {
+       public Control getControl();
+       public void addConversionListener(ConversionListener listener);
+       public void removeConversionListener(ConversionListener listener);
+       public void apply();
+       public Conversion<?> convert();
+}
+
+
+abstract class AbstractEditor implements OptionEditor {
+       private final List<ConversionListener> listeners;
+       protected final Option<?> option;
+       protected final Control control;
+
+       public AbstractEditor(Composite parent, Option<?> option) {
+               this.listeners = new ArrayList<ConversionListener>(1);
+               this.option = option;
+               this.control = createControl(parent, option);
+       }
+
+       
+       public Control getControl() {
+               return control;
+       }
+       
+       
+       public void addConversionListener(ConversionListener listener) {
+               listeners.add(listener);
+       }
+
+
+       public void removeConversionListener(ConversionListener listener) {
+               listeners.remove(listener);
+       }
+       
+       
+       protected void fireConversionPerformed(Conversion<?> conversion) {
+               for (ConversionListener listener : listeners) {
+                       listener.conversionPerformed(conversion);
+               }
+       }
+
+
+       protected abstract Control createControl(
+                       Composite parent, Option<?> option
+       );
+}
+
+
+class TextEditor extends AbstractEditor {
+       private Text text;
+       
+
+       public TextEditor(Composite parent, Option<?> option) {
+               super(parent, option);
+       }
+
+       
+       @Override
+       protected Control createControl(Composite parent, Option<?> opt) {
+               text = new Text(parent, SWT.BORDER);
+               text.setToolTipText(opt.getDescription());
+               text.setText(opt.getValue().toString());
+               
+               Verifier verifier = new Verifier();
+               text.addModifyListener(verifier);
+               text.addFocusListener(verifier);
+               
+               return text;
+       }
+       
+       
+       public void apply() {
+               option.setValue(text.getText());
+       }
+       
+       
+       public Conversion<?> convert() {
+               return option.convert(text.getText());
+       }
+       
+       
+       private final class Verifier extends FocusAdapter implements ModifyListener {
+               public void focusLost(FocusEvent e) {
+                       fireConversionPerformed(convert());
+               }
+
+
+               public void modifyText(ModifyEvent e) {
+                       fireConversionPerformed(convert());
+               }
+       }
+}
+
+
+class ComboEditor extends AbstractEditor {
+       private Combo combo;
+       private Object[] values;
+
+       
+       public ComboEditor(Composite parent, Option<?> option) {
+               super(parent, option);
+       }
+
+       
+       @Override
+       protected Control createControl(Composite parent, Option<?> opt) {
+               values = opt.values();
+               
+               combo = new Combo(parent, SWT.READ_ONLY);
+               combo.setToolTipText(opt.getDescription());     
+               
+               for (Object v : values) {
+                       combo.add(v.toString());
+               }
+               
+               combo.setText(opt.getValue().toString());
+               return combo;
+       }
+       
+
+       public void apply() {
+               int idx = combo.getSelectionIndex();
+               option.setValue(values[idx]);
+       }
+       
+       
+       public Conversion<?> convert() {
+               int idx = combo.getSelectionIndex();
+               return option.convert(values[idx]);
+       }
+}
+
+
+class ToggleEditor extends AbstractEditor {
+       private Button check;
+
+       
+       public ToggleEditor(Composite parent, Option<?> option) {
+               super(parent, option);
+       }
+
+
+       @Override
+       protected Control createControl(Composite parent, Option<?> opt) {
+               check = new Button(parent, SWT.CHECK);
+               Boolean value = (Boolean) opt.getValue();
+               check.setSelection(value);
+               check.addSelectionListener(new ToggleListener());
+               updateText();
+               return check;
+       }
+
+
+       private void updateText() {
+               boolean selection = check.getSelection();
+               check.setText(selection ? "Yes" : "No");
+       }
+
+
+       public void apply() {
+               option.setValue(check.getSelection());
+       }
+
+
+       public Conversion<?> convert() {
+               return option.convert(check.getSelection());
+       }
+       
+       
+       private final class ToggleListener extends SelectionAdapter {
+               public void widgetSelected(SelectionEvent e) {
+                       updateText();
+                       // No need to fire conversion event, will always be correct
+               }
+       }
+}
diff --git a/Annotation/src/ie/dcu/segment/options/TextEditor$1.class b/Annotation/src/ie/dcu/segment/options/TextEditor$1.class
new file mode 100644 (file)
index 0000000..841695c
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/options/TextEditor$1.class differ
diff --git a/Annotation/src/ie/dcu/segment/options/TextEditor$Verifier.class b/Annotation/src/ie/dcu/segment/options/TextEditor$Verifier.class
new file mode 100644 (file)
index 0000000..525a7ce
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/options/TextEditor$Verifier.class differ
diff --git a/Annotation/src/ie/dcu/segment/options/TextEditor.class b/Annotation/src/ie/dcu/segment/options/TextEditor.class
new file mode 100644 (file)
index 0000000..85a4a7a
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/options/TextEditor.class differ
diff --git a/Annotation/src/ie/dcu/segment/options/TextOption.class b/Annotation/src/ie/dcu/segment/options/TextOption.class
new file mode 100644 (file)
index 0000000..f43cc3d
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/options/TextOption.class differ
diff --git a/Annotation/src/ie/dcu/segment/options/TextOption.java b/Annotation/src/ie/dcu/segment/options/TextOption.java
new file mode 100644 (file)
index 0000000..ff41daa
--- /dev/null
@@ -0,0 +1,29 @@
+package ie.dcu.segment.options;
+
+/**
+ * A textual (string) segmentation algorithm parameter.
+ * 
+ * @author Kevin McGuinness
+ */
+public class TextOption extends AbstractOption<String> {
+
+       /**
+        * Create a text option with the given name, description, and default
+        * value.
+        * 
+        * @param name
+        *        The option name
+        * @param description
+        *        A description of the option
+        * @param def
+        *        The default value for the option
+        */
+       public TextOption(String name, String description, String def) {
+               super(OptionType.Text, name, description, def);
+       }
+
+
+       public Conversion<String> convert(Object value) {
+               return valid(value.toString());
+       }
+}
diff --git a/Annotation/src/ie/dcu/segment/options/ToggleEditor$1.class b/Annotation/src/ie/dcu/segment/options/ToggleEditor$1.class
new file mode 100644 (file)
index 0000000..84fa235
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/options/ToggleEditor$1.class differ
diff --git a/Annotation/src/ie/dcu/segment/options/ToggleEditor$ToggleListener.class b/Annotation/src/ie/dcu/segment/options/ToggleEditor$ToggleListener.class
new file mode 100644 (file)
index 0000000..fc0bb88
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/options/ToggleEditor$ToggleListener.class differ
diff --git a/Annotation/src/ie/dcu/segment/options/ToggleEditor.class b/Annotation/src/ie/dcu/segment/options/ToggleEditor.class
new file mode 100644 (file)
index 0000000..ff7efc6
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/options/ToggleEditor.class differ
diff --git a/Annotation/src/ie/dcu/segment/options/ToggleOption.class b/Annotation/src/ie/dcu/segment/options/ToggleOption.class
new file mode 100644 (file)
index 0000000..f94bcd6
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/options/ToggleOption.class differ
diff --git a/Annotation/src/ie/dcu/segment/options/ToggleOption.java b/Annotation/src/ie/dcu/segment/options/ToggleOption.java
new file mode 100644 (file)
index 0000000..c459fa1
--- /dev/null
@@ -0,0 +1,69 @@
+package ie.dcu.segment.options;
+
+/**
+ * A boolean segmentation algorithm parameter.
+ * 
+ * @author Kevin McGuinness
+ */
+public class ToggleOption extends AbstractOption<Boolean> {
+
+       /**
+        * Create a toggle option with the given name, description, and default
+        * value.
+        * 
+        * @param name
+        *        The option name
+        * @param description
+        *        A description of the option
+        * @param def
+        *        The default value for the option
+        */
+       public ToggleOption(String name, String description, boolean def) {
+               super(OptionType.Toggle, name, description, def);
+       }
+       
+
+       public Conversion<Boolean> convert(Object value) {
+               if (value instanceof Boolean) {
+                       return valid((Boolean) value);
+               } else if (value != null) {
+                       Boolean val = convert(value.toString());
+                       if (val != null) {
+                               return valid(val);
+                       }
+                       return invalid("%s is not a valid boolean, value = %s", getName(), value);
+               }
+               return invalid("value is null");
+       }
+       
+       
+       /**
+        * Performs a conversion from a string to a boolean. If the value is "yes",
+        * "true" or "1", then the result is <code>true</code>. Otherwise if the
+        * value is "no", "false" or "0" the result is <code>false</code>. Any
+        * other value produces <code>null</code>. The string is trimmed and case
+        * is ignored.
+        * 
+        * @param str
+        *          The string to convert.
+        * @return <code>true</code>, <code>false</code> or <code>null</code>.
+        */
+       private Boolean convert(String str) {
+               String v = str.trim();
+               
+               if (v.equalsIgnoreCase("true") || 
+                               v.equalsIgnoreCase("yes") || 
+                               v.equals("1")) 
+               {
+                       return true;
+                       
+               } else if (v.equalsIgnoreCase("false") || 
+                               v.equalsIgnoreCase("no") || 
+                               v.equals("0")) 
+               {
+                       return false;
+               }
+               
+               return null;
+       }
+}
diff --git a/Annotation/src/ie/dcu/segment/painters/CombinedPainter.class b/Annotation/src/ie/dcu/segment/painters/CombinedPainter.class
new file mode 100644 (file)
index 0000000..0b9388c
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/painters/CombinedPainter.class differ
diff --git a/Annotation/src/ie/dcu/segment/painters/CombinedPainter.java b/Annotation/src/ie/dcu/segment/painters/CombinedPainter.java
new file mode 100644 (file)
index 0000000..268a1dd
--- /dev/null
@@ -0,0 +1,136 @@
+package ie.dcu.segment.painters;
+
+import ie.dcu.segment.*;
+import ie.dcu.swt.ObservableImage;
+
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.widgets.*;
+
+/**
+ * An overlaid view of the image, segmentation mask, and markup.
+ * 
+ * @author Kevin McGuinness
+ */
+public class CombinedPainter implements SegmentationPainter {
+       public static final String NAME = "Combined";
+       
+       private ImageData maskData;
+       private Image maskImage;
+
+       
+       public String getName() {
+               return NAME;
+       }
+
+
+       public String getDescription() {
+               return "An overlaid view of the image, segmentation mask, and markup";
+       }
+
+
+       public void paint(SegmentationContext ctx, ObservableImage im) {
+
+               GC gc = im.beginPaint();
+
+               // Paint image
+               gc.drawImage(ctx.getImage(), 0, 0);
+
+               // Paint mask
+               createVisibleMask(ctx.getMask());
+               gc.drawImage(maskImage, 0, 0);
+
+               // Paint all annotations
+               ctx.getAnnotations().paint(im);
+               
+               // Commit changes
+               im.endPaint();
+       }
+
+
+       private void createVisibleMask(SegmentationMask mask) {
+               dispose();
+               
+               if (isNewMaskDataRequired(mask.getBounds())) {
+                       maskData = createMaskData(mask.getBounds());
+               } 
+               
+               // Blit in pixels
+               for (int y = 0, i = 0; y < mask.height; y++) {
+                       int rowOffset = y * maskData.bytesPerLine;
+                       for (int x = 0; x < mask.width; x++) {
+                               byte alpha, index;
+                               
+                               switch (mask.values[i]) {
+                               case SegmentationMask.BACKGROUND:
+                                       alpha = (byte) 128;
+                                       index = 2;
+                                       break;
+                               case SegmentationMask.FOREGROUND:
+                                       alpha = (byte) 128;
+                                       index = 1;
+                                       break;
+                               default:
+                                       alpha = 0;
+                                       index = 0;
+                                       break;
+                               }
+                                                               
+                               // The SWT ImageData buffer doesn't usually have it's rows aligned
+                               // contiguously in memory (i.e. there are > width bytes per scan-line in
+                               // the buffer), so we can't directly copy in at the same index as the
+                               // mask.
+                               maskData.data[x + rowOffset] = index;
+                               
+                               // However, the alpha data is always aligned correctly
+                               maskData.alphaData[i] = alpha;
+                               
+                               // Next location in the mask
+                               i++;
+                       }
+               }
+               
+               // Create new mask
+               maskImage = new Image(Display.getCurrent(), maskData);
+       }
+       
+       
+       private boolean isNewMaskDataRequired(Rectangle bounds) {
+               if (maskData == null) {
+                       return true;
+               } else {
+                       return maskData.width != bounds.width || maskData.height != bounds.height;
+               }
+       }
+
+
+       private static ImageData createMaskData(Rectangle bounds) {
+               RGB[] colors = new RGB[] {
+                       new RGB(128,128,128),
+                       new RGB(255,255,255),
+                       new RGB(0, 0, 0)
+               };
+               
+               // Create 3 color indexed palette
+               PaletteData palette = new PaletteData(colors);
+               
+               // Create 8 bit indexed image
+               ImageData data = new ImageData(bounds.width, bounds.height, 8, palette);
+               
+               // Create alpha mask
+               data.alphaData = new byte[bounds.width*bounds.height];
+               
+               // Create and return the image
+               return data;
+       }
+
+
+       public void dispose() {
+               // Dispose mask
+               if (maskImage != null) {
+                       if (!maskImage.isDisposed()) {
+                               maskImage.dispose();
+                       }
+                       maskImage = null;
+               }
+       }
+}
diff --git a/Annotation/src/ie/dcu/segment/painters/ForegroundOnlyPainter.class b/Annotation/src/ie/dcu/segment/painters/ForegroundOnlyPainter.class
new file mode 100644 (file)
index 0000000..8b2c9bb
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/painters/ForegroundOnlyPainter.class differ
diff --git a/Annotation/src/ie/dcu/segment/painters/ForegroundOnlyPainter.java b/Annotation/src/ie/dcu/segment/painters/ForegroundOnlyPainter.java
new file mode 100644 (file)
index 0000000..ed8bc4e
--- /dev/null
@@ -0,0 +1,114 @@
+package ie.dcu.segment.painters;
+
+
+import ie.dcu.segment.*;
+import ie.dcu.swt.ObservableImage;
+
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.widgets.*;
+
+/**
+ * Shows the foreground region of the image. The background is greyed out.
+ * 
+ * @author Kevin McGuinness
+ */
+public class ForegroundOnlyPainter implements SegmentationPainter {
+       
+       private ImageData maskData;
+       private Image maskImage;
+
+
+       public String getName() {
+               return "Foreground Only";
+       }
+
+
+       public String getDescription() {
+               return "Shows the foreground region of the image.";
+       }
+
+
+       public void paint(SegmentationContext ctx, ObservableImage im) {
+               GC gc = im.beginPaint();
+
+               // Paint image
+               gc.drawImage(ctx.getImage(), 0, 0);
+
+               // Paint mask
+               createVisibleMask(ctx.getMask());
+               gc.drawImage(maskImage, 0, 0);
+               
+               // Commit changes
+               im.endPaint();
+       }
+
+       
+       private void createVisibleMask(SegmentationMask mask) {
+               dispose();
+               
+               if (isNewMaskDataRequired(mask.getBounds())) {
+                       maskData = createMaskData(mask.getBounds());
+               } 
+               
+               // Blit in pixels
+               byte[] buff = new byte[maskData.width];
+               for (int y = 0, i = 0; y < mask.height; y++) {
+                       for (int x = 0; x < mask.width; x++) {
+                               switch (mask.values[i++]) {
+                               case SegmentationMask.BACKGROUND:
+                                       // black
+                                       buff[x] = 1; 
+                                       break;
+                               default:
+                                       // transparent
+                                       buff[x] = 0; 
+                               }
+                       }
+                       maskData.setPixels(0, y, buff.length, buff, 0);
+               }
+               
+               // Create new mask
+               maskImage = new Image(Display.getCurrent(), maskData);
+       }
+       
+       
+       private boolean isNewMaskDataRequired(Rectangle bounds) {
+               if (maskData == null) {
+                       return true;
+               } else {
+                       return maskData.width != bounds.width || maskData.height != bounds.height;
+               }
+       }
+
+
+       private static ImageData createMaskData(Rectangle bounds) {
+               RGB[] colors = new RGB[] {
+                       new RGB(255,255,255),
+                       new RGB(128,128,128)
+               };
+               
+               // Create binary indexed palette
+               PaletteData palette = new PaletteData(colors);
+               
+               // Create 1 bit indexed image 
+               ImageData data = new ImageData(
+                               bounds.width, bounds.height, 1, palette);
+               
+               // Set transparent pixel
+               data.transparentPixel = 0;
+               
+               // Create and return the image
+               return data;
+       }
+       
+
+       public void dispose() {
+               // Dispose mask
+               if (maskImage != null) {
+                       if (!maskImage.isDisposed()) {
+                               maskImage.dispose();
+                       }
+                       maskImage = null;
+               }
+       }
+}
diff --git a/Annotation/src/ie/dcu/segment/painters/LabelPainter.java b/Annotation/src/ie/dcu/segment/painters/LabelPainter.java
new file mode 100644 (file)
index 0000000..1362931
--- /dev/null
@@ -0,0 +1,114 @@
+package ie.dcu.segment.painters;
+
+
+import ie.dcu.segment.*;
+import ie.dcu.swt.ObservableImage;
+
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.widgets.*;
+
+/**
+ * Shows the foreground region of the image. The background is greyed out.
+ * 
+ * @author Kevin and Nikhil
+ */
+public class LabelPainter implements SegmentationPainter {
+       
+       private ImageData maskData;
+       private Image maskImage;
+
+
+       public String getName() {
+               return "Display Label";
+       }
+
+
+       public String getDescription() {
+               return "Shows the segmented piece with label attached.";
+       }
+
+
+       public void paint(SegmentationContext ctx, ObservableImage im) {
+               GC gc = im.beginPaint();
+
+               // Paint image
+               gc.drawImage(ctx.getImage(), 0, 0);
+
+               // Paint mask
+               createVisibleMask(ctx.getMask());
+               gc.drawImage(maskImage, 0, 0);
+               
+               // Commit changes
+               im.endPaint();
+       }
+
+       
+       private void createVisibleMask(SegmentationMask mask) {
+               dispose();
+               
+               if (isNewMaskDataRequired(mask.getBounds())) {
+                       maskData = createMaskData(mask.getBounds());
+               } 
+               
+               // Blit in pixels
+               byte[] buff = new byte[maskData.width];
+               for (int y = 0, i = 0; y < mask.height; y++) {
+                       for (int x = 0; x < mask.width; x++) {
+                               switch (mask.values[i++]) {
+                               case SegmentationMask.BACKGROUND:
+                                       // black
+                                       buff[x] = 1; 
+                                       break;
+                               default:
+                                       // transparent
+                                       buff[x] = 0; 
+                               }
+                       }
+                       maskData.setPixels(0, y, buff.length, buff, 0);
+               }
+               
+               // Create new mask
+               maskImage = new Image(Display.getCurrent(), maskData);
+       }
+       
+       
+       private boolean isNewMaskDataRequired(Rectangle bounds) {
+               if (maskData == null) {
+                       return true;
+               } else {
+                       return maskData.width != bounds.width || maskData.height != bounds.height;
+               }
+       }
+
+
+       private static ImageData createMaskData(Rectangle bounds) {
+               RGB[] colors = new RGB[] {
+                       new RGB(255,255,255),
+                       new RGB(128,128,128)
+               };
+               
+               // Create binary indexed palette
+               PaletteData palette = new PaletteData(colors);
+               
+               // Create 1 bit indexed image 
+               ImageData data = new ImageData(
+                               bounds.width, bounds.height, 1, palette);
+               
+               // Set transparent pixel
+               data.transparentPixel = 0;
+               
+               // Create and return the image
+               return data;
+       }
+       
+
+       public void dispose() {
+               // Dispose mask
+               if (maskImage != null) {
+                       if (!maskImage.isDisposed()) {
+                               maskImage.dispose();
+                       }
+                       maskImage = null;
+               }
+       }
+}
diff --git a/Annotation/src/ie/dcu/segment/painters/MarkupPainter.class b/Annotation/src/ie/dcu/segment/painters/MarkupPainter.class
new file mode 100644 (file)
index 0000000..4dbb4e7
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/painters/MarkupPainter.class differ
diff --git a/Annotation/src/ie/dcu/segment/painters/MarkupPainter.java b/Annotation/src/ie/dcu/segment/painters/MarkupPainter.java
new file mode 100644 (file)
index 0000000..24b5fbf
--- /dev/null
@@ -0,0 +1,48 @@
+package ie.dcu.segment.painters;
+
+
+import ie.dcu.segment.SegmentationContext;
+import ie.dcu.swt.*;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.GC;
+
+/**
+ * Shows the current markup (annotations) only
+ * 
+ * @author Kevin McGuinness
+ */
+public class MarkupPainter implements SegmentationPainter {
+       public static final String NAME = "Markup";
+
+
+       public String getDescription() {
+               return "Shows the current markup (annotations) only";
+       }
+
+
+       public String getName() {
+               return NAME;
+       }
+
+
+       public void paint(SegmentationContext ctx, ObservableImage im) {
+
+               GC gc = im.beginPaint();
+
+               // Paint white backdrop
+               SwtUtils.setBackground(gc, SWT.COLOR_WHITE);
+               gc.fillRectangle(im.getBounds());
+
+               // Paint all annotations
+               ctx.getAnnotations().paint(im);
+
+               // Commit changes
+               im.endPaint();
+       }
+       
+       
+       public void dispose() {
+               // Nothing needs to be disposed
+       }
+}
diff --git a/Annotation/src/ie/dcu/segment/painters/MaskPainter.class b/Annotation/src/ie/dcu/segment/painters/MaskPainter.class
new file mode 100644 (file)
index 0000000..8a236f0
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/painters/MaskPainter.class differ
diff --git a/Annotation/src/ie/dcu/segment/painters/MaskPainter.java b/Annotation/src/ie/dcu/segment/painters/MaskPainter.java
new file mode 100644 (file)
index 0000000..192f368
--- /dev/null
@@ -0,0 +1,98 @@
+package ie.dcu.segment.painters;
+
+import ie.dcu.segment.*;
+import ie.dcu.swt.ObservableImage;
+
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.widgets.*;
+
+/**
+ * Shows the current segmentation mask
+ * 
+ * @author Kevin McGuinness
+ */
+public class MaskPainter implements SegmentationPainter {
+       public static final String NAME = "Mask";
+
+       private ImageData maskData;
+       private Image maskImage;
+
+       public String getDescription() {
+               return "Shows the current segmentation mask";
+       }
+
+
+       public String getName() {
+               return NAME;
+       }
+
+
+       public void paint(SegmentationContext ctx, ObservableImage im) {
+
+               GC gc = im.beginPaint();
+               
+               // Paint mask
+               createVisibleMask(ctx.getMask());
+               gc.drawImage(maskImage, 0, 0);
+
+               // Commit changes
+               im.endPaint();
+       }
+       
+       
+       private void createVisibleMask(SegmentationMask mask) {
+               dispose();
+               
+               // Check if we have a compatible buffer
+               if (isNewMaskDataRequired(mask.getBounds())) {
+                       maskData = createMaskData(mask.getBounds());
+               } 
+               
+               // Blit in pixels
+               for (int y = 0; y < mask.height; y++) {
+                       int maskOffset = y * mask.width;
+                       int dataOffset = y * maskData.bytesPerLine;
+                       System.arraycopy(mask.values, maskOffset, maskData.data, dataOffset, mask.width);
+               }
+               
+               // Create new mask
+               maskImage = new Image(Display.getCurrent(), maskData);
+       }
+       
+       private boolean isNewMaskDataRequired(Rectangle bounds) {
+               if (maskData == null) {
+                       return true;
+               } else {
+                       return maskData.width != bounds.width || maskData.height != bounds.height;
+               }
+       }
+       
+       
+       private static ImageData createMaskData(Rectangle bounds) {
+               RGB[] colors = new RGB[] {
+                       new RGB(128,128,128),
+                       new RGB(255,255,255),
+                       new RGB(0, 0, 0)
+               };
+               
+               // Create 3 color indexed palette
+               PaletteData palette = new PaletteData(colors);
+               
+               // Create 8 bit indexed image
+               ImageData data = new ImageData(bounds.width, bounds.height, 8, palette);
+               
+               // Create and return the image
+               return data;
+       }
+
+
+       public void dispose() {
+               /// Dispose mask
+               if (maskImage != null) {
+                       if (!maskImage.isDisposed()) {
+                               maskImage.dispose();
+                       }
+                       maskImage = null;
+               }
+       }
+}
diff --git a/Annotation/src/ie/dcu/segment/painters/OriginalPainter.class b/Annotation/src/ie/dcu/segment/painters/OriginalPainter.class
new file mode 100644 (file)
index 0000000..70bbe58
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/painters/OriginalPainter.class differ
diff --git a/Annotation/src/ie/dcu/segment/painters/OriginalPainter.java b/Annotation/src/ie/dcu/segment/painters/OriginalPainter.java
new file mode 100644 (file)
index 0000000..97bdfca
--- /dev/null
@@ -0,0 +1,42 @@
+package ie.dcu.segment.painters;
+
+import ie.dcu.segment.SegmentationContext;
+import ie.dcu.swt.ObservableImage;
+
+import org.eclipse.swt.graphics.*;
+
+/**
+ * Shows the original image
+ * 
+ * @author Kevin McGuinness
+ */
+public class OriginalPainter implements SegmentationPainter {
+       public static final String NAME = "Original";
+
+
+       public String getDescription() {
+               return "Shows the original image";
+       }
+
+
+       public String getName() {
+               return NAME;
+       }
+
+
+       public void paint(SegmentationContext ctx, ObservableImage im) {
+               GC gc = im.beginPaint();
+
+               // Paint image
+               gc.drawImage(ctx.getImage(), 0, 0);
+
+               // Commit changes
+               im.endPaint();
+       }
+
+
+       public void dispose() {
+               // Nothing needs to be disposed
+       }
+       
+}
diff --git a/Annotation/src/ie/dcu/segment/painters/OutlineOverlayPainter.class b/Annotation/src/ie/dcu/segment/painters/OutlineOverlayPainter.class
new file mode 100644 (file)
index 0000000..fe61d10
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/painters/OutlineOverlayPainter.class differ
diff --git a/Annotation/src/ie/dcu/segment/painters/OutlineOverlayPainter.java b/Annotation/src/ie/dcu/segment/painters/OutlineOverlayPainter.java
new file mode 100644 (file)
index 0000000..41cc8d6
--- /dev/null
@@ -0,0 +1,145 @@
+package ie.dcu.segment.painters;
+
+import ie.dcu.segment.*;
+import ie.dcu.swt.ObservableImage;
+
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.widgets.*;
+
+/**
+ * Shows an an overlay of foreground border on the image
+ * 
+ * @author Kevin McGuinness
+ */
+public class OutlineOverlayPainter implements SegmentationPainter {
+       
+       private ImageData maskData;
+       private Image maskImage;
+
+       public String getName() {
+               return "Outline Overlaid";
+       }
+
+
+       public String getDescription() {
+               return "Shows an an overlay of foreground border on the image";
+       }
+
+
+       public void paint(SegmentationContext ctx, ObservableImage im) {
+               GC gc = im.beginPaint();
+
+               // Paint image
+               gc.drawImage(ctx.getImage(), 0, 0);
+
+               // Paint mask
+               createVisibleMask(ctx.getMask());
+               gc.drawImage(maskImage, 0, 0);
+               
+               // Commit changes
+               im.endPaint();
+       }
+
+       
+       private void createVisibleMask(SegmentationMask mask) {
+               dispose();
+               
+               if (isNewMaskDataRequired(mask.getBounds())) {
+                       maskData = createMaskData(mask.getBounds());
+               } 
+               
+               // Set pixels
+               byte[] buff = new byte[maskData.width];
+               for (int y = 0, i = 0; y < mask.height-1; y++) {
+                       for (int x = 0; x < mask.width-1; x++) {
+                               // Make transparent
+                               buff[x] = 0;
+                               
+                               // Current pixel
+                               byte pix1 = mask.values[i];
+                               
+                               // Neighbor to right & neighbor below
+                               byte pix2 = mask.values[i+1];
+                               byte pix3 = mask.values[i+mask.width];
+                               
+                               // Set pixel if either neighbor is different
+                               if (pix1 != pix2 || pix1 != pix3) {
+                                       buff[x] = 1;
+                               }
+                               
+                               // Next pixel
+                               i++;
+                       }
+                       
+                       if (mask.width != 0) {
+                               // Last pixel in row
+                               byte pix1 = mask.values[i];
+                               byte pix2 = mask.values[i+mask.width];
+                               buff[mask.width-1] = (pix1 != pix2) ? (byte) 1 : 0;
+                               
+                               // Next row
+                               i++;
+                       }
+                       
+                       // Blit pixels
+                       maskData.setPixels(0, y, buff.length, buff, 0);
+               }
+               
+               // Last row
+               if (mask.height != 0) {
+                       int yoff = (mask.height - 1) * mask.width;
+                       for (int x = 0; x < mask.width-1; x++) {
+                               byte pix1 = mask.values[x+yoff];
+                               byte pix2 = mask.values[x+yoff+1];
+                               buff[x] = (pix1 != pix2) ? (byte) 1 : 0;
+                       }
+                       
+                       // Blit
+                       maskData.setPixels(0, mask.height-1, buff.length, buff, 0);
+               }
+               
+               // Create new mask
+               maskImage = new Image(Display.getCurrent(), maskData);
+       }
+       
+       
+       private boolean isNewMaskDataRequired(Rectangle bounds) {
+               if (maskData == null) {
+                       return true;
+               } else {
+                       return maskData.width != bounds.width || maskData.height != bounds.height;
+               }
+       }
+
+
+       private static ImageData createMaskData(Rectangle bounds) {
+               RGB[] colors = new RGB[] {
+                       new RGB(255,255,255),
+                       new RGB(255,0,0)
+               };
+               
+               // Create binary indexed palette
+               PaletteData palette = new PaletteData(colors);
+               
+               // Create 1 bit indexed image 
+               ImageData data = new ImageData(
+                               bounds.width, bounds.height, 1, palette);
+               
+               // Set transparent pixel
+               data.transparentPixel = 0;
+               
+               // Create and return the image
+               return data;
+       }
+       
+
+       public void dispose() {
+               // Dispose mask
+               if (maskImage != null) {
+                       if (!maskImage.isDisposed()) {
+                               maskImage.dispose();
+                       }
+                       maskImage = null;
+               }
+       }
+}
diff --git a/Annotation/src/ie/dcu/segment/painters/SegmentationPainter.class b/Annotation/src/ie/dcu/segment/painters/SegmentationPainter.class
new file mode 100644 (file)
index 0000000..eadcd40
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/painters/SegmentationPainter.class differ
diff --git a/Annotation/src/ie/dcu/segment/painters/SegmentationPainter.java b/Annotation/src/ie/dcu/segment/painters/SegmentationPainter.java
new file mode 100644 (file)
index 0000000..4989f60
--- /dev/null
@@ -0,0 +1,39 @@
+package ie.dcu.segment.painters;
+
+import ie.dcu.segment.SegmentationContext;
+import ie.dcu.swt.ObservableImage;
+
+/**
+ * Interface for classes that can be used to visualize an image and it's
+ * segmentation mask.
+ * 
+ * 
+ * @author Kevin McGuinness
+ */
+public interface SegmentationPainter {
+
+       /**
+        * Returns the painter name (Shown in the UI)
+        */
+       public String getName();
+
+       /**
+        * Returns a description of the painter.
+        */
+       public String getDescription();
+
+       /**
+        * Paint the segmentation context onto the observable image
+        * 
+        * @param ctx
+        *        The current segmentation context.
+        * @param im
+        *        An observable image instance.
+        */
+       public void paint(SegmentationContext ctx, ObservableImage im);
+
+       /**
+        * Dispose of any resources (SWT image objects, colors, etc.)
+        */
+       public void dispose();
+}
diff --git a/Annotation/src/ie/dcu/segment/util/AbstractSegmenter.class b/Annotation/src/ie/dcu/segment/util/AbstractSegmenter.class
new file mode 100644 (file)
index 0000000..38a83d6
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/util/AbstractSegmenter.class differ
diff --git a/Annotation/src/ie/dcu/segment/util/AbstractSegmenter.java b/Annotation/src/ie/dcu/segment/util/AbstractSegmenter.java
new file mode 100644 (file)
index 0000000..c8e8928
--- /dev/null
@@ -0,0 +1,226 @@
+package ie.dcu.segment.util;
+
+
+
+import ie.dcu.array.Arrays;
+import ie.dcu.image.binary.MorphOp;
+import ie.dcu.matrix.*;
+import ie.dcu.segment.*;
+import ie.dcu.segment.annotate.Annotation;
+import ie.dcu.segment.options.Option;
+
+import java.util.*;
+import java.util.logging.*;
+
+/**
+ * Abstract implementation of a {@link Segmenter} object.
+ * 
+ * @author Kevin McGuinness
+ */
+public abstract class AbstractSegmenter implements Segmenter {
+
+       /**
+        * Segmenter options map.
+        */
+       private final Map<String, Option<?>> options;
+       
+       
+       /**
+        * Logger for subclass messages.
+        */
+       protected final Logger log;
+       
+       
+       /**
+        * Name of the segmentation algorithm. Should be set by subclass during 
+        * construction.
+        */
+       protected String name;
+       
+       
+       /**
+        * Description of the segmentation algorithm. Should be set by subclass 
+        * during construction.
+        */
+       protected String description;
+       
+       
+       /**
+        * Vendor of the segmentation algorithm. Should be set by subclass 
+        * during construction. This should be either the author of the 
+        * segmentation algorithm, or a company or institution name.
+        */
+       protected String vendor;
+       
+       
+       /**
+        * Default return value for the {@link #isFast()} method, 
+        * <code>false</code> by default.
+        */
+       protected boolean fast;
+       
+       
+       /**
+        * Flag that indicates if the segmentation algorithm is available on the 
+        * current platform. Defaults to <code>true</code>.
+        */
+       protected boolean available;
+       
+       
+       /**
+        * Constructor.
+        */
+       public AbstractSegmenter() {
+               options = new LinkedHashMap<String, Option<?>>();
+               log = Logger.getLogger(getClass().getSimpleName());
+               name = "";
+               description = "";
+               vendor = "";
+               available = true;
+       }
+       
+       
+       /**
+        * Default implementation returns the {@link #available} field.
+        */
+       public boolean isAvailable() {
+               return available;
+       }
+       
+       
+       /**
+        * Default implementation returns the {@link #name} field.
+        */
+       public String getName() {
+               return name;
+       }
+
+
+       /**
+        * Default implementation returns the {@link #description} field.
+        */
+       public String getDescription() {
+               return description;
+       }
+
+
+       /**
+        * Default implementation returns the {@link #vendor} field.
+        */
+       public String getVendor() {
+               return vendor;
+       }
+
+
+       /**
+        * Default implementation returns the {@link #options} map.
+        */
+       public Collection<Option<?>> getOptions() {
+               return Collections.unmodifiableCollection(options.values());
+       }
+
+
+       /**
+        * Default implementation returns the {@link #fast} field.
+        */
+       public boolean isFast() {
+               return fast;
+       }
+
+
+       /**
+        * Default implementation calls {@link #segment(SegmentationContext)}.
+        */
+       public void added(SegmentationContext ctx, Annotation a) {
+               segment(ctx);
+       }
+
+
+       /**
+        * Default implementation calls {@link #segment(SegmentationContext)}.
+        */
+       public void removed(SegmentationContext ctx, Annotation a) {
+               segment(ctx);
+       }
+
+
+       /**
+        * Default implementation calls {@link #segment(SegmentationContext)}.
+        */
+       public void update(SegmentationContext ctx) {
+               segment(ctx);
+       }
+
+
+
+       /**
+        * Perform a full update of the segmentation.
+        * 
+        * @param ctx
+        *          The segmentation context.
+        */
+       protected abstract void segment(SegmentationContext ctx);
+       
+       
+       
+       /**
+        * Add an option (parameter) to the {@link #options} map.
+        * 
+        * @param option
+        *          The option
+        */
+       protected void add(Option<?> option) {
+               options.put(option.getName(), option);
+       }
+       
+       
+       /**
+        * Get an option (parameter) from the {@link #options} map.
+        * 
+        * @param <T>
+        *          The option type.
+        * @param clazz
+        *          The option class.
+        * @param option
+        *          The option name.
+        * @return The option.
+        */
+       protected <T> T get(Class<T> clazz, String option) {
+               Option<?> opt = options.get(option);
+               return clazz.cast(opt.getValue());
+       }
+       
+       /**
+        * Perform a morphological smooth on the contour of the given segmentation
+        * mask.
+        * 
+        * @param mask
+        *        A segmentation mask.
+        */
+       protected void smoothContour(SegmentationMask mask) {
+               // TODO: Maybe optimize this? The old MorphOps.smooth might be faster
+               MorphOp op = new MorphOp.Smooth();
+               op.setForegroundValue(SegmentationMask.FOREGROUND);
+               op.setBackgroundValue(SegmentationMask.BACKGROUND);
+               op.setInputProvider(mask);
+               ByteMatrix matrix = (ByteMatrix)
+                       op.getMatrix(Matrix.Type.Byte, false);
+               Arrays.copy(matrix.values, mask.values);
+       }
+
+       /**
+        * Copy the non-zero markup pixels to the segmentation mask.
+        * 
+        * @param mask
+        *            The segmentation mask.
+        * @param markup
+        *            The rasterized markup pixels.
+        */
+       protected void retainMarkup(SegmentationMask mask, byte[] markup) {
+               for (int i = 0; i < markup.length; i++) {
+                       if (markup[i] != 0) {
+                               mask.values[i] = markup[i];
+                       }
+               }
+       }
+}
diff --git a/Annotation/src/ie/dcu/segment/util/AnnotationRasterizer$1.class b/Annotation/src/ie/dcu/segment/util/AnnotationRasterizer$1.class
new file mode 100644 (file)
index 0000000..d6f5b16
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/util/AnnotationRasterizer$1.class differ
diff --git a/Annotation/src/ie/dcu/segment/util/AnnotationRasterizer.class b/Annotation/src/ie/dcu/segment/util/AnnotationRasterizer.class
new file mode 100644 (file)
index 0000000..2ef4569
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/util/AnnotationRasterizer.class differ
diff --git a/Annotation/src/ie/dcu/segment/util/AnnotationRasterizer.java b/Annotation/src/ie/dcu/segment/util/AnnotationRasterizer.java
new file mode 100644 (file)
index 0000000..144d40c
--- /dev/null
@@ -0,0 +1,145 @@
+package ie.dcu.segment.util;
+
+import ie.dcu.segment.annotate.*;
+
+import java.awt.*;
+import java.awt.image.*;
+import java.util.List;
+
+import org.eclipse.swt.graphics.Point;
+
+/**
+ * Rasterize the annotations using the Graphics2D API. The annotations are drawn
+ * onto a byte buffer, with one byte per pixel.
+ * 
+ * @author Kevin McGuinness
+ */
+public class AnnotationRasterizer {
+       private static final byte[] R = { (byte) 128, (byte) 255, (byte)   0 };
+       private static final byte[] G = { (byte) 128, (byte)   0, (byte)   0 };
+       private static final byte[] B = { (byte) 128, (byte)   0, (byte) 255 };
+       
+       private static final Color[] COLORS = {
+               new Color(128, 128, 128),
+               new Color(255,   0,   0),
+               new Color(  0,   0, 255)
+       };
+       
+       private static final ColorModel cm = new IndexColorModel(8,3,R,G,B);
+       
+       private final int width;
+       private final int height;
+       private final int npixels;
+       private final WritableRaster wr;
+       private final BufferedImage im;
+       private transient byte[] buff;
+       
+       public AnnotationRasterizer(int width, int height) {
+               this.width = width;
+               this.height = height;
+               this.npixels = width * height;
+               this.wr = cm.createCompatibleWritableRaster(width, height);
+               this.im = new BufferedImage(cm, wr, false, null);
+       }
+       
+       
+       public byte[] rasterize(AnnotationManager am) {
+               paint(am);
+               return getDataBuffer();
+       }
+       
+       
+       private void paint(AnnotationManager am) {
+               
+               Graphics2D g = im.createGraphics();
+               
+               // Clear background
+               g.setColor(COLORS[0]);
+               g.fillRect(0, 0, width, height);
+               
+               // For each annotation
+               int lastWidth = -1;
+               for (Annotation a : am.annotations()) {
+                       
+                       List<Point> pts = a.points();
+                       
+                       // Skip empty
+                       if (pts.size() == 0) {
+                               continue;
+                       }
+                       
+                       // Check if we need to change the stroke
+                       int width = a.getLineWidth();
+                       if (width != lastWidth) {
+                               g.setStroke(createStroke(width));
+                               lastWidth = width;
+                       }
+                       
+                       // Set the color
+                       switch (a.getType()) {
+                       case Foreground:
+                               g.setColor(COLORS[1]);
+                               break;
+                       case Background:
+                               g.setColor(COLORS[2]);
+                               break;
+                       }
+                       
+                       // Paint the points
+                       if (pts.size() > 1) {
+                               Point last = null;
+                               for (Point p : pts) {
+                                       if (last != null) {
+                                               g.drawLine(last.x, last.y, p.x, p.y);
+                                       }
+                                       
+                                       last = p;
+                               }
+                       } else {
+                               // If only one point
+                               Point p = pts.get(0);
+                               g.drawLine(p.x, p.y, p.x, p.y);
+                       }
+               }
+               
+               // Commit changes
+               g.dispose();
+       }
+       
+       
+       private byte[] getDataBuffer() { 
+               
+               // Optimize the typical case by avoiding a copy if unnecessary.
+               DataBuffer buffer = wr.getDataBuffer();
+               if (buffer instanceof DataBufferByte) {
+                       
+                       // Good, we have a compatible data buffer
+                       DataBufferByte bytebuf = (DataBufferByte) buffer;
+                       int banks = bytebuf.getNumBanks();
+                       if (banks == 1) {
+                               
+                               // Smashin, only one data bank is in use
+                               byte[] buff = bytebuf.getData();
+                               
+                               // Sanity check
+                               if (buff.length == npixels) {
+                                       return buff;
+                               }
+                       }
+               }
+               
+               // Handle some unexpected data buffer by copying pixels
+               if (buff == null) {
+                       buff = new byte[npixels];
+               }
+                               
+               return (byte[]) wr.getDataElements(0, 0, width, height, buff);
+       }
+       
+       
+       
+       private static final Stroke createStroke(int width) {
+               return new BasicStroke(width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
+       }
+       
+}
diff --git a/Annotation/src/ie/dcu/segment/util/ImageArgbConverter.class b/Annotation/src/ie/dcu/segment/util/ImageArgbConverter.class
new file mode 100644 (file)
index 0000000..27b92b2
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/util/ImageArgbConverter.class differ
diff --git a/Annotation/src/ie/dcu/segment/util/ImageArgbConverter.java b/Annotation/src/ie/dcu/segment/util/ImageArgbConverter.java
new file mode 100644 (file)
index 0000000..ab314ed
--- /dev/null
@@ -0,0 +1,99 @@
+package ie.dcu.segment.util;
+
+import org.eclipse.swt.graphics.*;
+
+/**
+ * Convert a SWT ImageData object to a linear array of ARGB integers (alpha
+ * channel is ignored).
+ * 
+ * @author Kevin McGuinness
+ */
+public class ImageArgbConverter {
+       private final int npixels;
+       private final int[] pixels;
+       
+       /**
+        * Create an converter object for images of the given size.
+        * 
+        * @param width
+        *        The image width.
+        * @param height
+        *        The image height.
+        */
+       public ImageArgbConverter(int width, int height) {
+               npixels = width*height;
+               pixels = new int[npixels];
+       }
+       
+       
+       /**
+        * Convert an SWT ImageData object to a linear array of integers. Each
+        * integer is a contains the red, green, and blue channels, ordered as
+        * 0x00RRGGBB. The alpha channel is ignored.
+        * 
+        * @param data
+        *        An image data object.
+        * @param clone
+        *        If <code>false</code> returns a shared array, otherwise returns a
+        *        new array.
+        * @return A int array of ARGB values in row-major order.
+        */
+       public int[] convert(ImageData data, boolean clone) {
+               PaletteData p = data.palette;
+               
+               data.getPixels(0, 0, npixels, pixels, 0);
+               if (p.isDirect) {
+                       for (int i = 0; i < npixels; i++) {
+                               // Unpack
+                               int r, g, b, pel = pixels[i];
+                               
+                               // red
+                               r = pel & p.redMask;
+                               r = (p.redShift < 0) ? 
+                                               r >>> -p.redShift : r << p.redShift;
+                               
+                               // green
+                               g = pel & p.greenMask;
+                               g = (p.greenShift < 0) ? 
+                                               g >>> -p.greenShift : g << p.greenShift;
+                               
+                               // blue
+                               b = pel & p.blueMask;
+                               b = (p.blueShift < 0) ? 
+                                               b >>> -p.blueShift : b << p.blueShift;
+                               
+                               // re-pack
+                               pixels[i] = pack(r, g, b);
+                       }
+               } else {
+                       // Indirect palette
+                       for (int i = 0; i < npixels; i++) {
+                               RGB color = p.colors[pixels[i]];
+                               pixels[i] = pack(color.red, color.green, color.blue);
+                       }
+               }
+               
+               if (clone) {
+                       return pixels.clone();
+               }
+               
+               return pixels;
+       }
+       
+       /**
+        * Convert an SWT ImageData object to a linear array of integers. Each
+        * integer is a contains the red, green, and blue channels, ordered as
+        * 0x00RRGGBB. The alpha channel is ignored.
+        * 
+        * @param data
+        *        An image data object.
+        * @return A int array of ARGB values in row-major order.
+        */
+       public static int[] convert(ImageData data) {
+               return new ImageArgbConverter(data.width, data.height).convert(data, false);
+       }
+       
+       private static final int pack(int r, int g, int b) {
+               return 0x00ffffff & ((r << 16) | (g << 8) | b);
+       }
+}
diff --git a/Annotation/src/ie/dcu/segment/util/ImageByteConverter.class b/Annotation/src/ie/dcu/segment/util/ImageByteConverter.class
new file mode 100644 (file)
index 0000000..460930d
Binary files /dev/null and b/Annotation/src/ie/dcu/segment/util/ImageByteConverter.class differ
diff --git a/Annotation/src/ie/dcu/segment/util/ImageByteConverter.java b/Annotation/src/ie/dcu/segment/util/ImageByteConverter.java
new file mode 100644 (file)
index 0000000..df33c66
--- /dev/null
@@ -0,0 +1,101 @@
+package ie.dcu.segment.util;
+
+import org.eclipse.swt.graphics.*;
+
+/**
+ * Converts an SWT ImageData object to a linear array of bytes. 
+ * 
+ * @author Kevin McGuinness
+ */
+public class ImageByteConverter {
+       private final int npixels;
+       private final int nsamples;
+       private final int[] pixels;
+       private final byte[] samples;
+       
+       /**
+        * Create an converter object for images of the given size.
+        * 
+        * @param width
+        *        The image width.
+        * @param height
+        *        The image height.
+        */
+       public ImageByteConverter(int width, int height) {
+               this.npixels = width*height;
+               this.nsamples = npixels*3;
+               this.pixels = new int[npixels];
+               this.samples = new byte[nsamples];
+       }
+       
+       /**
+        * Convert an SWT ImageData object to a linear array of bytes. The returned
+        * array contains three bytes per pixel, and is in row-major order. The
+        * bytes are ordered RGB.
+        * 
+        * @param data
+        *        An image data object.
+        * @param clone
+        *        If <code>false</code> returns a shared array, otherwise returns a
+        *        new array.
+        * @return A byte array of RGB values in row-major order.
+        */
+       public byte[] convert(ImageData data, boolean clone) {
+               PaletteData p = data.palette;
+               
+               data.getPixels(0, 0, npixels, pixels, 0);
+               if (p.isDirect) {
+                       for (int i = 0, j = 0; i < npixels; i++) {
+                               // Unpack
+                               int r, g, b, pel = pixels[i];
+                               
+                               // red
+                               r = pel & p.redMask;
+                               r = (p.redShift < 0) ? 
+                                               r >>> -p.redShift : r << p.redShift;
+                               
+                               // green
+                               g = pel & p.greenMask;
+                               g = (p.greenShift < 0) ? 
+                                               g >>> -p.greenShift : g << p.greenShift;
+                               
+                               // blue
+                               b = pel & p.blueMask;
+                               b = (p.blueShift < 0) ? 
+                                               b >>> -p.blueShift : b << p.blueShift;
+                               
+                               // assign
+                               samples[j++] = (byte) r;
+                               samples[j++] = (byte) g;
+                               samples[j++] = (byte) b;
+                       }
+               } else {
+                       // Indirect palette
+                       for (int i = 0, j = 0; i < npixels; i++) {
+                               RGB color = p.colors[pixels[i]];
+                               samples[j++] = (byte) color.red;
+                               samples[j++] = (byte) color.green;
+                               samples[j++] = (byte) color.blue;
+                       }
+               }
+               
+               if (clone) {
+                       return samples.clone();
+               }
+               
+               return samples;
+       }
+       
+       /**
+        * Convert an SWT image data object to a linear array of bytes. The returned
+        * array contains three bytes per pixel, and is in row-major order. The
+        * bytes are ordered RGB. 
+        * 
+        * @param data
+        *        An image data object.
+        * @return A byte array of RGB values in row-major order.
+        */
+       public static byte[] convert(ImageData data) {
+               return new ImageByteConverter(data.width, data.height).convert(data, false);
+       }
+}
diff --git a/Annotation/src/ie/dcu/stats/InversionMethod$1.class b/Annotation/src/ie/dcu/stats/InversionMethod$1.class
new file mode 100644 (file)
index 0000000..8f7acd5
Binary files /dev/null and b/Annotation/src/ie/dcu/stats/InversionMethod$1.class differ
diff --git a/Annotation/src/ie/dcu/stats/InversionMethod.class b/Annotation/src/ie/dcu/stats/InversionMethod.class
new file mode 100644 (file)
index 0000000..e68f5be
Binary files /dev/null and b/Annotation/src/ie/dcu/stats/InversionMethod.class differ
diff --git a/Annotation/src/ie/dcu/stats/InversionMethod.java b/Annotation/src/ie/dcu/stats/InversionMethod.java
new file mode 100644 (file)
index 0000000..24cb901
--- /dev/null
@@ -0,0 +1,254 @@
+package ie.dcu.stats;
+
+import java.awt.*;
+import java.awt.geom.*;
+
+import javax.swing.*;
+
+import ie.dcu.array.Arrays;
+import static java.awt.RenderingHints.*;
+
+/**
+ * Implementation of the inversion method for simulating random variables.
+ * 
+ * @author Kevin McGuinness
+ */
+public final class InversionMethod {
+
+       /**
+        * The probability distribution function
+        */
+       private final double[] pdf;
+       
+       /**
+        * The cumulative distribution function
+        */
+       private final double[] cdf;
+       
+       
+       /**
+        * Initialize the inversion method with the given discrete probability
+        * distribution function. The distribution function will be normalized the
+        * sum of all it's elements is one.
+        * 
+        * The values of the pdf function must be all greater than 0 and contain at
+        * least one positive value.
+        * 
+        * @param pdf
+        *            A probability distribution function.
+        */
+       public InversionMethod(double[] pdf) {
+               this.pdf = normalize(check(pdf));
+               this.cdf = cumsum(this.pdf);
+       }
+       
+       /**
+        * Returns the distribution size
+        */
+       public final int size() {
+               return this.pdf.length;
+       }
+       
+       /**
+        * Extract a random variable from to the distribution.
+        * 
+        * The returned value is in the range [0..n) where n is the size of the
+        * distribution.
+        * 
+        * Complexity is O(log(n)).
+        * 
+        * @return A random variable
+        */
+       public final int random() {
+               return lbound(cdf, Math.random());
+       }
+       
+       /**
+        * Returns the arg min{x : array[x] >= value}
+        * 
+        * Complexity is O(log(n)).
+        */
+       private static int lbound(double[] array, double value) {
+               int lo = 0;
+               int hi = array.length - 1;
+               while (lo <= hi) {
+                       int mid = (lo + hi) >> 1;
+                       double x = array[mid];
+                       
+                       if (x < value) {
+                               lo = mid + 1;
+                       } else if (x > value) {
+                               hi = mid - 1;
+                       } else {
+                               return mid;
+                       }
+               }
+               return lo;
+       }
+       
+       /**
+        * Check the values of the pdf function are ok.
+        */
+       private static double[] check(double[] pdf) {
+               double min = Arrays.min(pdf);
+               if (min < 0) {
+                       throw new IllegalArgumentException("pdf contains values < 0");
+               }
+               
+               double max = Arrays.max(pdf);
+               if (max == 0) {
+                       throw new IllegalArgumentException("pdf contains no nonzero values");
+               }
+               
+               return pdf;
+       }
+
+       /**
+        * Normalize the pdf function so that it sums to 1.
+        */
+       private static double[] normalize(double[] pdf) {
+               double[] result = new double[pdf.length];
+               
+               double sum = Arrays.sum(pdf);
+               for (int i = 0; i < pdf.length; i++) {
+                       result[i] = pdf[i] / sum;
+               }
+       
+               return result;
+       }
+
+       /**
+        * Calculate the cumulative sum of the array.
+        */
+       private static double[] cumsum(double[] array) {
+               double[] result = new double[array.length];
+               
+               double sum = 0.0;
+               for (int i = 0; i < array.length; i++) {
+                       sum += array[i];
+                       result[i] = sum;
+               }
+               
+               return result;
+       }
+       
+       public static void main(String[] args) {
+               
+               double[] pdf = normal(5); //{1,2,3,4,5,4,5,3,2,1};
+               InversionMethod var = new InversionMethod(pdf);
+               int[] variables = new int[10000];
+               for (int i = 0; i < variables.length; i++) {
+                       variables[i] = var.random();
+               }
+               plothist("Normal Distribution", variables);
+       }
+       
+       public static double[] normal(int n) {
+               double[] result = new double[2*n+1];
+               double sigma = n / 3.0;
+               System.out.println(sigma);
+               double scalef = 1.0 / (Math.sqrt(2.0*Math.PI) * sigma);
+               double denom = 2*sigma*sigma;
+               
+               for (int i = -n; i <= n; i++) {
+                       result[i+n] = scalef * Math.exp(-(i*i)/denom);
+               }
+               return result;
+       }
+       
+       
+       private static JFrame plothist(String title, int[] values) {
+               final int[] hist = histogram(values);
+               final Color[] colors = new Color[hist.length];
+               for (int i = 0; i < colors.length; i++) {
+                       float r = (float) Math.random();
+                       float g = (float) Math.random();
+                       float b = (float) Math.random();
+                       colors[i] = new Color(r,g,b);
+               }
+               
+               
+               JFrame frame = new JFrame(title);
+               JPanel panel = new JPanel() {
+                       private static final long serialVersionUID = 1L;
+                       public void paint(Graphics graphics) {
+                               Graphics2D g = (Graphics2D) graphics;
+                               FontMetrics fontMetrics = g.getFontMetrics();
+                               
+                               double w = getWidth();
+                               double h = getHeight();
+                               double spaceAtBottom = fontMetrics.getHeight() + 4;
+                               double spaceAtTop = 3;
+                               double spaceBetweenBars = 5;
+                               
+                               g.setRenderingHint(KEY_ANTIALIASING, VALUE_ANTIALIAS_ON);
+                               g.setRenderingHint(KEY_TEXT_ANTIALIASING, VALUE_TEXT_ANTIALIAS_ON);
+                               g.setRenderingHint(KEY_FRACTIONALMETRICS, VALUE_FRACTIONALMETRICS_ON);
+                               
+                               g.setColor(Color.white);
+                               g.fill(new Rectangle2D.Double(0,0,w,h));
+                               g.setColor(Color.black);
+                               g.draw(new Line2D.Double(0,h-spaceAtBottom,w,h-spaceAtBottom));
+                               
+                               double hmax = Arrays.max(hist);
+                               double hcount = hist.length;
+                               double space = w / hcount;
+                               
+                               Rectangle2D.Double bar = new Rectangle2D.Double(0,0,0,0);
+                               
+                               for (int i = 0; i < hist.length; i++) {
+                                       bar.x = i * space + spaceBetweenBars / 2;
+                                       bar.width = space - spaceBetweenBars;
+                                       bar.height = (h-(spaceAtBottom+spaceAtTop)) * (hist[i] / hmax);
+                                       bar.y = h - bar.height - spaceAtBottom;
+                                       g.setColor(colors[i]);
+                                       g.fill(bar);
+                                       g.setColor(Color.black);
+                                       g.draw(bar);
+                                       
+                                       String text = String.valueOf(hist[i]);
+                                       Rectangle2D bounds = fontMetrics.getStringBounds(text, g);
+                                       double tx = bar.getCenterX() - bounds.getWidth() / 2.0;
+                                       double ty = bar.getMinY() + bounds.getHeight() + 1;
+                                       if (ty > h - spaceAtBottom - 1) {
+                                               // place over the bar
+                                               ty = bar.getMinY() - 2;
+                                       }
+                                       g.drawString(text, (int) tx, (int) ty);
+                                       
+                                       text = String.valueOf(i);
+                                       bounds = fontMetrics.getStringBounds(text, g);
+                                       tx = bar.getCenterX() - bounds.getWidth() / 2.0;
+                                       ty = bar.getMaxY() + bounds.getHeight();
+                                       g.drawString(text, (int) tx, (int) ty);
+                               }
+                       }
+                       
+                       public Dimension getPreferredSize() {
+                               Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
+                               int w = 50 * hist.length;
+                               int h = 400;
+                               w = Math.min(Math.max(w, 100), screenSize.width);
+                               h = Math.min(h, screenSize.height);
+                               return new Dimension(w,h);
+                       }
+               };
+               
+               frame.setLayout(new BorderLayout());
+               frame.add(panel);
+               frame.pack();
+               frame.setLocationRelativeTo(frame);
+               frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+               frame.setVisible(true);
+               return frame;
+       }
+       
+       private static int[] histogram(int[] values) {
+               int[] bins = new int[Arrays.max(values)+1];
+               java.util.Arrays.fill(bins, 0);
+               for (int i = 0; i < values.length; i++) {
+                       bins[values[i]]++;
+               }
+               return bins;
+       }
+}
diff --git a/Annotation/src/ie/dcu/swt/CocoaUIEnhancer$1.class b/Annotation/src/ie/dcu/swt/CocoaUIEnhancer$1.class
new file mode 100644 (file)
index 0000000..73a5ef6
Binary files /dev/null and b/Annotation/src/ie/dcu/swt/CocoaUIEnhancer$1.class differ
diff --git a/Annotation/src/ie/dcu/swt/CocoaUIEnhancer$2.class b/Annotation/src/ie/dcu/swt/CocoaUIEnhancer$2.class
new file mode 100644 (file)
index 0000000..b1c0f13
Binary files /dev/null and b/Annotation/src/ie/dcu/swt/CocoaUIEnhancer$2.class differ
diff --git a/Annotation/src/ie/dcu/swt/CocoaUIEnhancer.class b/Annotation/src/ie/dcu/swt/CocoaUIEnhancer.class
new file mode 100644 (file)
index 0000000..3665245
Binary files /dev/null and b/Annotation/src/ie/dcu/swt/CocoaUIEnhancer.class differ
diff --git a/Annotation/src/ie/dcu/swt/CocoaUIEnhancer.java b/Annotation/src/ie/dcu/swt/CocoaUIEnhancer.java
new file mode 100644 (file)
index 0000000..0903932
--- /dev/null
@@ -0,0 +1,288 @@
+package ie.dcu.swt;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.internal.C;
+import org.eclipse.swt.internal.Callback;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Listener;
+
+/**
+ * Provide a hook to connecting the Preferences, About and Quit menu items of
+ * the Mac OS X Application menu when using the SWT Cocoa bindings.
+ * <p>
+ * This code does not require the Cocoa SWT JAR in order to be compiled as it
+ * uses reflection to access the Cocoa specific API methods. It does, however,
+ * depend on JFace (for IAction), but you could easily modify the code to use
+ * SWT Listeners instead in order to use this class in SWT only applications.
+ * </p>
+ */
+public class CocoaUIEnhancer {
+
+       private static final int kAboutMenuItem = 0;
+       private static final int kPreferencesMenuItem = 2;
+       private static final int kQuitMenuItem = 10;
+
+       static long sel_toolbarButtonClicked_;
+       static long sel_preferencesMenuItemSelected_;
+       static long sel_aboutMenuItemSelected_;
+
+       static Callback proc3Args;
+
+       private final String appName;
+
+       /**
+        * Construct a new CocoaUIEnhancer.
+        * 
+        * @param appName
+        *        The name of the application. It will be used to customize the
+        *        About and Quit menu items. If you do not wish to customize the
+        *        About and Quit menu items, just pass <tt>null</tt> here.
+        */
+       public CocoaUIEnhancer(String appName) {
+               this.appName = appName;
+       }
+
+       /**
+        * Hook the given Listener to the Mac OS X application Quit menu and the
+        * IActions to the About and Preferences menus.
+        * 
+        * @param display
+        *        The Display to use.
+        * @param quitListener
+        *        The listener to invoke when the Quit menu is invoked.
+        * @param aboutAction
+        *        The action to run when the About menu is invoked.
+        * @param preferencesAction
+        *        The action to run when the Preferences menu is invoked.
+        */
+       public void hookApplicationMenu(Display display, Listener quitListener,
+               final IAction aboutAction, final IAction preferencesAction) {
+               Object target = new Object() {
+                       
+                       // For the 32 bit JVM
+                       @SuppressWarnings("unused")
+                       int actionProc(int id, int sel, int arg) {
+                               return (int) actionProc((long) id, (long) sel, (long) arg);
+                       }
+                       
+                       // For the 64 bit JVM
+                       long actionProc(long id, long sel, long arg) {
+                               if (sel == sel_aboutMenuItemSelected_) {
+                                       aboutAction.run();
+                               } else if (sel == sel_preferencesMenuItemSelected_) {
+                                       preferencesAction.run();
+                               } 
+                               return 99;
+                       }
+               };
+
+               try {
+                       // Initialize the menuItems.
+                       initialize(target);
+               } catch (Exception e) {
+                       throw new IllegalStateException(e);
+               }
+
+               // Connect the quit/exit menu.
+               if (!display.isDisposed()) {
+                       display.addListener(SWT.Close, quitListener);
+               }
+
+               // Schedule disposal of callback object
+               display.disposeExec(new Runnable() {
+                       public void run() {
+                               invoke(proc3Args, "dispose");
+                       }
+               });
+       }
+
+       private void initialize(Object callbackObject) throws Exception {
+
+               Class<?> osCls = classForName("org.eclipse.swt.internal.cocoa.OS");
+
+               // Register names in objective-c.
+               if (sel_toolbarButtonClicked_ == 0) {
+                       // sel_toolbarButtonClicked_ = registerName( osCls, "toolbarButtonClicked:" ); //$NON-NLS-1$
+                       sel_preferencesMenuItemSelected_ = registerName(osCls,
+                               "preferencesMenuItemSelected:"); //$NON-NLS-1$
+                       sel_aboutMenuItemSelected_ = registerName(osCls,
+                               "aboutMenuItemSelected:"); //$NON-NLS-1$
+               }
+
+               // Create an SWT Callback object that will invoke the actionProc method
+               // of our internal callbackObject.
+               proc3Args = new Callback(callbackObject, "actionProc", 3); //$NON-NLS-1$
+               Method getAddress = Callback.class
+                       .getMethod("getAddress", new Class[0]);
+               Object object = getAddress.invoke(proc3Args, (Object[]) null);
+               long proc3 = convertToLong(object);
+               if (proc3 == 0) {
+                       SWT.error(SWT.ERROR_NO_MORE_CALLBACKS);
+               }
+
+               Class<?> nsmenuCls = classForName("org.eclipse.swt.internal.cocoa.NSMenu");
+               Class<?> nsmenuitemCls = classForName("org.eclipse.swt.internal.cocoa.NSMenuItem");
+               Class<?> nsstringCls = classForName("org.eclipse.swt.internal.cocoa.NSString");
+               Class<?> nsapplicationCls = classForName("org.eclipse.swt.internal.cocoa.NSApplication");
+
+               // Instead of creating a new delegate class in objective-c,
+               // just use the current SWTApplicationDelegate. An instance of this
+               // is a field of the Cocoa Display object and is already the target
+               // for the menuItems. So just get this class and add the new methods
+               // to it.
+               object = invoke(osCls, "objc_lookUpClass",
+                       new Object[] { "SWTApplicationDelegate" });
+               long cls = convertToLong(object);
+
+               // Add the action callbacks for Preferences and About menu items.
+               invoke(osCls, "class_addMethod", new Object[] { wrapPointer(cls),
+                       wrapPointer(sel_preferencesMenuItemSelected_), wrapPointer(proc3),
+                       "@:@" }); //$NON-NLS-1$
+               invoke(osCls, "class_addMethod",
+                       new Object[] { wrapPointer(cls),
+                               wrapPointer(sel_aboutMenuItemSelected_), wrapPointer(proc3),
+                               "@:@" }); //$NON-NLS-1$
+
+               // Get the Mac OS X Application menu.
+               Object sharedApplication = invoke(nsapplicationCls, "sharedApplication");
+               Object mainMenu = invoke(sharedApplication, "mainMenu");
+               Object mainMenuItem = invoke(nsmenuCls, mainMenu, "itemAtIndex",
+                       new Object[] { wrapPointer(0) });
+               Object appMenu = invoke(mainMenuItem, "submenu");
+
+               // Create the About <application-name> menu command
+               Object aboutMenuItem = invoke(nsmenuCls, appMenu, "itemAtIndex",
+                       new Object[] { wrapPointer(kAboutMenuItem) });
+               if (appName != null) {
+                       Object nsStr = invoke(nsstringCls, "stringWith",
+                               new Object[] { "About " + appName });
+                       invoke(nsmenuitemCls, aboutMenuItem, "setTitle",
+                               new Object[] { nsStr });
+               }
+               // Rename the quit action.
+               if (appName != null) {
+                       Object quitMenuItem = invoke(nsmenuCls, appMenu, "itemAtIndex",
+                               new Object[] { wrapPointer(kQuitMenuItem) });
+                       Object nsStr = invoke(nsstringCls, "stringWith",
+                               new Object[] { "Quit " + appName });
+                       invoke(nsmenuitemCls, quitMenuItem, "setTitle",
+                               new Object[] { nsStr });
+               }
+
+               // Enable the Preferences menuItem.
+               Object prefMenuItem = invoke(nsmenuCls, appMenu, "itemAtIndex",
+                       new Object[] { wrapPointer(kPreferencesMenuItem) });
+               invoke(nsmenuitemCls, prefMenuItem, "setEnabled", new Object[] { true });
+
+               // Set the action to execute when the About or Preferences menuItem is
+               // invoked.
+               //
+               // We don't need to set the target here as the current target is the
+               // SWTApplicationDelegate
+               // and we have registerd the new selectors on it. So just set the new
+               // action to invoke the
+               // selector.
+               invoke(nsmenuitemCls, prefMenuItem, "setAction",
+                       new Object[] { wrapPointer(sel_preferencesMenuItemSelected_) });
+               invoke(nsmenuitemCls, aboutMenuItem, "setAction",
+                       new Object[] { wrapPointer(sel_aboutMenuItemSelected_) });
+       }
+
+       private long registerName(Class<?> osCls, String name)
+               throws IllegalArgumentException, SecurityException,
+               IllegalAccessException, InvocationTargetException,
+               NoSuchMethodException {
+               Object object = invoke(osCls, "sel_registerName", new Object[] { name });
+               return convertToLong(object);
+       }
+
+       private long convertToLong(Object object) {
+               if (object instanceof Integer) {
+                       Integer i = (Integer) object;
+                       return i.longValue();
+               }
+               if (object instanceof Long) {
+                       Long l = (Long) object;
+                       return l.longValue();
+               }
+               return 0;
+       }
+
+       private static Object wrapPointer(long value) {
+               Class<?> PTR_CLASS = C.PTR_SIZEOF == 8 ? long.class : int.class;
+               if (PTR_CLASS == long.class)
+                       return new Long(value);
+               else
+                       return new Integer((int) value);
+       }
+
+       private static Object invoke(Class<?> clazz, String methodName,
+               Object[] args) {
+               return invoke(clazz, null, methodName, args);
+       }
+
+       private static Object invoke(Class<?> clazz, Object target,
+               String methodName, Object[] args) {
+               try {
+                       Class<?>[] signature = new Class<?>[args.length];
+                       for (int i = 0; i < args.length; i++) {
+                               Class<?> thisClass = args[i].getClass();
+                               if (thisClass == Integer.class)
+                                       signature[i] = int.class;
+                               else if (thisClass == Long.class)
+                                       signature[i] = long.class;
+                               else if (thisClass == Byte.class)
+                                       signature[i] = byte.class;
+                               else if (thisClass == Boolean.class)
+                                       signature[i] = boolean.class;
+                               else
+                                       signature[i] = thisClass;
+                       }
+                       Method method = clazz.getMethod(methodName, signature);
+                       return method.invoke(target, args);
+               } catch (Exception e) {
+                       throw new IllegalStateException(e);
+               }
+       }
+
+       private Class<?> classForName(String classname) {
+               try {
+                       Class<?> cls = Class.forName(classname);
+                       return cls;
+               } catch (ClassNotFoundException e) {
+                       throw new IllegalStateException(e);
+               }
+       }
+
+       private Object invoke(Class<?> cls, String methodName) {
+               return invoke(cls, methodName, (Class<?>[]) null, (Object[]) null);
+       }
+
+       private Object invoke(Class<?> cls, String methodName,
+               Class<?>[] paramTypes, Object... arguments) {
+               try {
+                       Method m = cls.getDeclaredMethod(methodName, paramTypes);
+                       return m.invoke(null, arguments);
+               } catch (Exception e) {
+                       throw new IllegalStateException(e);
+               }
+       }
+
+       private Object invoke(Object obj, String methodName) {
+               return invoke(obj, methodName, (Class<?>[]) null, (Object[]) null);
+       }
+
+       private Object invoke(Object obj, String methodName, Class<?>[] paramTypes,
+               Object... arguments) {
+               try {
+                       Method m = obj.getClass().getDeclaredMethod(methodName, paramTypes);
+                       return m.invoke(obj, arguments);
+               } catch (Exception e) {
+                       throw new IllegalStateException(e);
+               }
+       }
+}
\ No newline at end of file
diff --git a/Annotation/src/ie/dcu/swt/CursorFactory.class b/Annotation/src/ie/dcu/swt/CursorFactory.class
new file mode 100644 (file)
index 0000000..2ae4c07
Binary files /dev/null and b/Annotation/src/ie/dcu/swt/CursorFactory.class differ
diff --git a/Annotation/src/ie/dcu/swt/CursorFactory.java b/Annotation/src/ie/dcu/swt/CursorFactory.java
new file mode 100644 (file)
index 0000000..bee86a7
--- /dev/null
@@ -0,0 +1,78 @@
+package ie.dcu.swt;
+
+import java.util.*;
+
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.widgets.*;
+
+/**
+ * Create cursors.
+ * 
+ * @author Kevin McGuinness
+ */
+public class CursorFactory {
+               
+       /**
+        * Create a cross-hair cursor.
+        * 
+        * @return The newly created cursor.
+        */
+       public static Cursor createCrosshairCursor() {
+               
+               // Size of cursor
+               final int s = 24;
+               
+               // Number of points in cursor
+               final int n = s*s;
+               
+               // Midpoint of cursor
+               final int m = s/2;
+               
+               // Color indices
+               final byte black = 1;
+               final byte light = 2;
+               final byte trans = 0;
+               
+               // Cursor array
+               byte[] cursor = new byte[n];
+               
+               // Flood with transparency
+               Arrays.fill(cursor, (byte) 0);
+               
+               // Set crosshair pixels
+               for (int i = 0; i < s; i++) {
+                       
+                       // Choose color
+                       byte color = (i == m-2 || i == m+2) ? light : black;
+                                               
+                       // Set pixels
+                       if (i < m-1 || i > m+1) {       
+                               int idx1 = i+m*s;
+                               int idx2 = m+i*s;
+                               cursor[idx1] = (byte) color;
+                               cursor[idx2] = (byte) color;
+                       } 
+               }
+               
+               // Set center pixel
+               cursor[m+m*s] = black;
+               
+               // Create colors
+               RGB[] colors = new RGB[] { 
+                               new RGB(255,255,255), 
+                               new RGB(0,0,0),
+                               new RGB(128,128,128)
+               };
+               
+               // Create palette
+               PaletteData palette = new PaletteData(colors);
+               
+               // Create image
+               ImageData image = new ImageData(s, s, 4, palette);
+               image.transparentPixel = trans;
+               image.setPixels(0, 0, n, cursor, 0);
+               
+               // Create cursor
+               return new Cursor(Display.getCurrent(), image, s/2, s/2);
+       }
+}
diff --git a/Annotation/src/ie/dcu/swt/Dispatcher.class b/Annotation/src/ie/dcu/swt/Dispatcher.class
new file mode 100644 (file)
index 0000000..f4123d5
Binary files /dev/null and b/Annotation/src/ie/dcu/swt/Dispatcher.class differ
diff --git a/Annotation/src/ie/dcu/swt/Dispatcher.java b/Annotation/src/ie/dcu/swt/Dispatcher.java
new file mode 100644 (file)
index 0000000..ceeea48
--- /dev/null
@@ -0,0 +1,98 @@
+package ie.dcu.swt;
+
+import java.io.Serializable;
+import java.lang.reflect.*;
+import java.util.logging.*;
+
+import org.eclipse.swt.widgets.*;
+
+/**
+ * Dispatch simple method calls by reflection.
+ * 
+ * @author Kevin McGuinness
+ */
+public class Dispatcher implements Serializable, Listener {
+       
+       /**
+        * Serialization UID
+        */
+       private static final long serialVersionUID = -8518627659417915880L;
+       
+       /**
+        * Logger used to report errors.
+        */
+       private static final Logger logger = Logger.getLogger("Dispatcher");
+       
+       /**
+        * The target object.
+        */
+       public final Object object;
+       
+       /**
+        * The target method.
+        */
+       public final Method method;
+
+       /**
+        * Create a dispatcher that calls the given method on the given object. The
+        * method should have no parameters. If a SecurityException or a
+        * NoSuchMethodException occurs when getting the Method object, then it is
+        * logged and wrapped in a RuntimeException and re-thrown.
+        * 
+        * @param object
+        *            The target object.
+        * @param method
+        *            The method name.
+        * @throws RuntimeException
+        *             If a SecurityException or NoSuchMethodException occurs.
+        */
+       public Dispatcher(Object object, String method) 
+               throws RuntimeException 
+       {
+               try {
+                       this.object = object;
+                       this.method = object.getClass().getMethod(method);
+               } catch (SecurityException e) {
+                       logger.log(Level.SEVERE, "Cannot get method by reflection", e);
+                       throw new RuntimeException(e);
+               } catch (NoSuchMethodException e) {
+                       logger.log(Level.SEVERE, "Method not found: " + method, e);
+                       throw new RuntimeException(e);
+               }
+       }
+
+       /**
+        * Invoke the method on the object by reflection. If any exception occurs in
+        * the invocation, it is logged, then wrapped in a RuntimeException and
+        * re-thrown.
+        * 
+        * @return The result of the method invocation, or null if the method is
+        *         void.
+        * 
+        * @throws RuntimeException
+        *             If any exception occurs in the invocation, it is wrapped in a
+        *             RuntimeException and re-thrown.
+        */
+       public Object invoke() {
+               try {
+                       return method.invoke(object);
+               } catch (IllegalArgumentException e) {
+                       logger.log(Level.SEVERE, "Error invoking method", e);
+                       throw new RuntimeException(e);
+               } catch (IllegalAccessException e) {
+                       logger.log(Level.SEVERE, "Error invoking method", e);
+                       throw new RuntimeException(e);
+               } catch (InvocationTargetException e) {
+                       logger.log(Level.WARNING, "Invocation target error", e);
+                       throw new RuntimeException(e);
+               }
+       }
+
+       /**
+        * Allows the dispatcher to be used as an SWT listener. The event and
+        * return value are ignored.
+        */
+       public void handleEvent(Event event) {
+               invoke();
+       }
+}
diff --git a/Annotation/src/ie/dcu/swt/EventDispatcher.class b/Annotation/src/ie/dcu/swt/EventDispatcher.class
new file mode 100644 (file)
index 0000000..e9c40ca
Binary files /dev/null and b/Annotation/src/ie/dcu/swt/EventDispatcher.class differ
diff --git a/Annotation/src/ie/dcu/swt/EventDispatcher.java b/Annotation/src/ie/dcu/swt/EventDispatcher.java
new file mode 100644 (file)
index 0000000..0b7b577
--- /dev/null
@@ -0,0 +1,104 @@
+package ie.dcu.swt;
+
+
+import java.io.Serializable;
+import java.lang.reflect.*;
+import java.util.logging.*;
+
+import org.eclipse.swt.widgets.*;
+
+/**
+ * Dispatches method calls that take an Event parameter by reflection.
+ * 
+ * @author Kevin McGuinness
+ */
+public class EventDispatcher implements Serializable, Listener {
+
+       /**
+        * Serialization UID.
+        */
+       private static final long serialVersionUID = 7238671421599697388L;
+
+       /**
+        * Logger used to report errors.
+        */
+       private static final Logger logger = Logger.getLogger("Dispatcher");
+       
+       /**
+        * The target object.
+        */
+       public final Object object;
+       
+       /**
+        * The target method.
+        */
+       public final Method method;
+
+       /**
+        * Create an event dispatcher that calls the given method on the given
+        * object. The method must take a single Event parameter. If a
+        * SecurityException or a NoSuchMethodException occurs when getting the
+        * Method object, then it is logged and wrapped in a RuntimeException and
+        * re-thrown.
+        * 
+        * @param object
+        *            The target object.
+        * @param method
+        *            The method name.
+        * @throws RuntimeException
+        *             If a SecurityException or NoSuchMethodException occurs.
+        */
+       public EventDispatcher(Object object, String method) 
+               throws RuntimeException 
+       {
+               try {
+                       this.object = object;
+                       this.method = object.getClass().getMethod(method, Event.class);
+               } catch (SecurityException e) {
+                       logger.log(Level.SEVERE, "Cannot get method by reflection", e);
+                       throw new RuntimeException(e);
+               } catch (NoSuchMethodException e) {
+                       logger.log(Level.SEVERE, "Method not found: " + method, e);
+                       throw new RuntimeException(e);
+               }
+       }
+       
+       /**
+        * Invoke the method on the object by reflection. If any exception occurs in
+        * the invocation, it is logged, then wrapped in a RuntimeException and 
+        * re-thrown.
+        * 
+        * @param event
+        *            The event to pass to the method invocation.
+        * 
+        * @return The result of the method invocation, or null if the method is
+        *         void.
+        * 
+        * @throws RuntimeException
+        *             If any exception occurs in the invocation, it is wrapped in a
+        *             RuntimeException and re-thrown.
+        */
+       public Object invoke(Event event) throws RuntimeException {
+               try {
+                       return method.invoke(object, event);
+               } catch (IllegalArgumentException e) {
+                       logger.log(Level.SEVERE, "Error invoking method", e);
+                       throw new RuntimeException(e);
+               } catch (IllegalAccessException e) {
+                       logger.log(Level.SEVERE, "Error invoking method", e);
+                       throw new RuntimeException(e);
+               } catch (InvocationTargetException e) {
+                       logger.log(Level.WARNING, "Invocation target error", e);
+                       throw new RuntimeException(e);
+               }
+       }
+
+       /**
+        * Allows the dispatcher to be used as an SWT listener. The event is 
+        * passed to the method and the return value is ignored.
+        */
+       public void handleEvent(Event event) {
+               invoke(event);
+       }
+
+}
diff --git a/Annotation/src/ie/dcu/swt/ImageControl$1.class b/Annotation/src/ie/dcu/swt/ImageControl$1.class
new file mode 100644 (file)
index 0000000..59c4ce2
Binary files /dev/null and b/Annotation/src/ie/dcu/swt/ImageControl$1.class differ
diff --git a/Annotation/src/ie/dcu/swt/ImageControl$2.class b/Annotation/src/ie/dcu/swt/ImageControl$2.class
new file mode 100644 (file)
index 0000000..3fc5551
Binary files /dev/null and b/Annotation/src/ie/dcu/swt/ImageControl$2.class differ
diff --git a/Annotation/src/ie/dcu/swt/ImageControl$3.class b/Annotation/src/ie/dcu/swt/ImageControl$3.class
new file mode 100644 (file)
index 0000000..b2fa9dc
Binary files /dev/null and b/Annotation/src/ie/dcu/swt/ImageControl$3.class differ
diff --git a/Annotation/src/ie/dcu/swt/ImageControl$4.class b/Annotation/src/ie/dcu/swt/ImageControl$4.class
new file mode 100644 (file)
index 0000000..ce55445
Binary files /dev/null and b/Annotation/src/ie/dcu/swt/ImageControl$4.class differ
diff --git a/Annotation/src/ie/dcu/swt/ImageControl.class b/Annotation/src/ie/dcu/swt/ImageControl.class
new file mode 100644 (file)
index 0000000..22ca344
Binary files /dev/null and b/Annotation/src/ie/dcu/swt/ImageControl.class differ
diff --git a/Annotation/src/ie/dcu/swt/ImageControl.java b/Annotation/src/ie/dcu/swt/ImageControl.java
new file mode 100644 (file)
index 0000000..ade7104
--- /dev/null
@@ -0,0 +1,969 @@
+package ie.dcu.swt;
+
+
+import ie.dcu.swt.event.*;
+
+import java.util.*;
+import java.util.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.ScrolledComposite;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.*;
+
+public class ImageControl extends Composite {
+       
+       /**
+        * Minimum allowed zoom level (5% of original).
+        */
+       public static final float MIN_ZOOM = 0.05f;
+       
+       
+       /**
+        * Maximum allowed zoom level (1000% of original)
+        */
+       public static final float MAX_ZOOM = 10.f;
+       
+       /**
+        * Default zoom in/out step (10%)
+        */
+       public static final float DEFAULT_ZOOM_STEP = 0.1f;
+       
+       
+       /**
+        * Default zoom level (100%)
+        */
+       public static final float DEFAULT_ZOOM = 1.0f;
+       
+       
+       /**
+        * Canvas where the image is drawn.
+        */
+       private final Canvas canvas;
+       
+       
+       /**
+        * Scroll bars.
+        */
+       private final ScrolledComposite scroller;
+       
+       
+       /**
+        * The images bounding rectangle (after scaling + translation).
+        */
+       private final Rectangle bounds;
+       
+       
+       /**
+        * Listeners for zoom events.
+        */
+       private final List<ZoomListener> listeners;
+       
+       
+       /**
+        * The original image.
+        */
+       private ObservableImage image;
+       
+       
+       /**
+        * The scaled image instance.
+        */
+       private Image scaled;
+       
+       
+       /**
+        * Current zoom level.
+        */
+       private float scale;
+       
+       
+       /**
+        * Current zoom in/out step.
+        */
+       private float scaleStep;
+       
+       
+       /**
+        * Flag to indicate that a black line border around the image
+        * should be painted. Default is <code>true</code>.
+        */
+       private boolean drawBorder;
+       
+       
+       /**
+        * Cached original image bounding rectangle.
+        */
+       private transient Rectangle cachedImageBounds;
+       
+       
+       /**
+        * Construct an image view. The style can be any style that a Composite can
+        * have. The parent may not be {@code null}. Although this class extends
+        * Composite, it does not make sense to set a layout on it or to add other
+        * widgets to it.
+        * 
+        * @param parent
+        *          The parent Composite.
+        * @param style
+        *          Style constants.
+        */
+       public ImageControl(Composite parent, int style) {
+               super(parent, style);
+               
+               // Fill entire composite
+               setLayout(new FillLayout());
+               
+               // Create scroll bars (always shown)
+               scroller = new ScrolledComposite(this, SWT.H_SCROLL | SWT.V_SCROLL);
+               
+               // Create canvas (set no background for efficiency, we'll draw it ourselves)
+               canvas = new Canvas(scroller, SWT.NO_BACKGROUND);
+               
+               // Initial bounds is an empty rectangle
+               bounds = new Rectangle(0, 0, 0, 0);
+               
+               // Zoom listeners
+               listeners = new ArrayList<ZoomListener>(2);
+               
+               // Setup scroll bars
+               scroller.setExpandHorizontal(true);
+               scroller.setExpandVertical(true);
+               scroller.setContent(canvas);
+               
+               // Listen for paint events and repaint canvas
+               canvas.addPaintListener(new PaintListener() {
+                       public void paintControl(PaintEvent e) {
+                               paintCanvas(e.gc);
+                       }
+               });
+               
+               // Listen for resizes and handle appropriately 
+               scroller.addControlListener(new ControlAdapter() {
+                       public void controlResized(ControlEvent e) {
+                               handleResize();
+                       }
+               });
+               
+               // Listen for dispose event
+               this.addDisposeListener(new DisposeListener() {
+                       public void widgetDisposed(DisposeEvent e) {
+                               handleDispose();
+                       }
+               });
+               
+               // Set defaults
+               scale = DEFAULT_ZOOM;
+               scaleStep = DEFAULT_ZOOM_STEP;
+               drawBorder = true;
+       }
+
+
+       /**
+        * Called when the scroll area is resized
+        */
+       protected void handleResize() {
+               repaint();
+       }
+       
+       
+       /**
+        * Handle a dispose event.
+        */
+       protected void handleDispose() {
+               // Throw away the scaled image
+               disposeScaledImage();
+       }
+       
+
+       /**
+        * Called when the canvas needs to be painted.
+        * 
+        * @param gc
+        *          The paint graphics context.
+        */
+       protected void paintCanvas(GC gc) {
+               
+               // Determine the clip (visible canvas area)
+               Rectangle clip = getVisibleCanvasArea();
+               
+               if (!hasImage()) {
+                       // Fill background
+                       gc.fillRectangle(clip);
+                       
+                       return;
+               }
+               
+               if (!hasScaledImage()) {
+                       // Create a scaled version of the image
+                       createScaledImage();
+               }
+               
+               // Set the clip
+               gc.setClipping(clip);
+               
+               // Draw the scaled image
+               gc.drawImage(scaled, bounds.x, bounds.y);
+               
+           // Draw background
+               int tGap = bounds.y - clip.y; 
+               int bGap = bounds.y + bounds.height - clip.y + clip.height;
+               int lGap = bounds.x - clip.x;
+               int rGap = bounds.x + bounds.width - clip.x + clip.width;
+               
+               if (bounds.height < clip.height) {
+                       gc.fillRectangle(clip.x, clip.y, clip.width, tGap);
+                       gc.fillRectangle(clip.x, bounds.y + bounds.height, clip.width, bGap);
+               }
+               
+               if (bounds.width < clip.width) {
+                       gc.fillRectangle(clip.x, clip.y + tGap, lGap, bounds.height);
+                       gc.fillRectangle(bounds.x + bounds.width, clip.y + tGap, 
+                                       rGap, bounds.height);
+               }
+               
+               // Draw a border around the image
+               if (drawBorder) {
+                       SwtUtils.setForeground(gc, SWT.COLOR_BLACK);
+                       gc.drawRectangle(bounds.x-1, bounds.y-1, bounds.width+1, bounds.height+1);
+               }
+       }
+       
+       
+       /**
+        * Handles changes in the image data.
+        */
+       protected void handleImageChanged(ImageEvent e) {
+                       
+               // If dimensions changed, re-constructed entire scaled image
+               if (e.dimensionsChanged()) {
+                       cachedImageBounds = null;
+                       createScaledImage();
+                       return;
+               }
+                       
+                       
+               // If no scaled image available, construct one
+               if (!hasScaledImage()) {
+                       recomputeBounds();
+                       
+                       // Construct scaled image
+                       scaled = new Image(getDisplay(), 
+                                       bounds.width, bounds.height);
+               }                       
+               
+               Rectangle modified = 
+                       e.modified.intersection(getImageBounds());
+                                       
+               // Scale modified rectangle
+               Rectangle target = 
+                       SwtUtils.scale(modified, scale);
+               
+               // Create graphics context
+               GC gc = new GC(scaled);
+               
+               // Set clip
+               gc.setClipping(target);
+               
+               // Redraw modified part
+               gc.drawImage(
+                               image.getImage(), 
+                               modified.x, 
+                               modified.y, 
+                               modified.width, 
+                               modified.height, 
+                               target.x, 
+                               target.y,
+                               target.width,
+                               target.height
+               );
+                       
+               // Dispose graphics context
+               gc.dispose();           
+               
+               // Repaint canvas
+               repaint(modified);
+       }
+
+
+       /**
+        * Returns the properly scaled version of the current image, after zooming has
+        * been performed. Returns <code>null</code> if there is no current image.
+        * 
+        * @return The scaled image, or <code>null</code>.
+        */
+       public Image getScaledImage() {
+               if (!hasScaledImage()) {
+                       createScaledImage();
+               }
+               return scaled;
+       }
+       
+       
+       /**
+        * Get the current image. Returns {@code null} if there is none.
+        * 
+        * @return The image, or <code>null</code>.
+        */
+       public ObservableImage getImage() {
+               return image;
+       }
+       
+
+       /**
+        * Set the currently displayed image. This method has no effect if the given
+        * image is the same as the currently displayed one. Otherwise, the image is
+        * set to the new one, the zoom is reset to 1.0 and the control is repainted.
+        * The given image may also be {@code null} to clear the display to its
+        * background color.
+        * 
+        * <p><b>Note:</b> The old image is <i>not</i> disposed of. 
+        * 
+        * @param image
+        *          The image, or <code>null</code>.
+        */
+       public void setImage(ObservableImage image) {
+               if (this.image != image) {
+                       // Dispose of scaled image
+                       disposeScaledImage();
+                       
+                       // Remove old listener
+                       if (this.image != null) {
+                               this.image.removeImageListener(imageListener);
+                       }
+                       
+                       // Set image
+                       this.image = image;
+                       
+                       // Add new listener
+                       if (this.image != null) {
+                               this.image.addImageListener(imageListener);
+                       }
+                       
+                       // Invalidate cached bounds
+                       this.cachedImageBounds = null;
+                       
+                       // Reset scale
+                       this.scale = 1.0f;
+                       
+                       // Repaint
+                       repaint();
+               }
+       }
+       
+       
+       /**
+        * Set flag to indicate that a black line border around the image will be
+        * drawn. Will repaint if changed.
+        * 
+        * @param drawBorder
+        *          <code>true</code> to draw a border.
+        */
+       public void setDrawBorder(boolean drawBorder) {
+               if (this.drawBorder != drawBorder) {
+                       this.drawBorder = drawBorder;
+                       repaint();
+               }
+       }
+       
+       
+       /**
+        * Returns <code>true</code> if the drawBorder flag is set.
+        * 
+        * @return <code>true</code> if a black border around the image will be
+        *         drawn.
+        * @see ImageControl#setDrawBorder(boolean)
+        */
+       public boolean getDrawBorder() {
+               return drawBorder;
+       }
+       
+       
+       
+       /**
+        * Returns {@code true} if the view has an image and it has not been disposed.
+        * 
+        * @return <code>true</code> if view has an image
+        */
+       public boolean hasImage() {
+               return image != null && !image.isDisposed();
+       }
+       
+       
+       /**
+        * Set the currently displayed image. This method has no effect if the given
+        * image is the same as the currently displayed one. Otherwise, the image is
+        * set to the new one, the zoom is reset to 1.0 and the control is repainted.
+        * The given image may also be {@code null} to clear the display to its
+        * background color.
+        * 
+        * @param image
+        *          The image, or <code>null</code>.
+        * @param disposeOld
+        *          If <code>true</code> the old image is disposed of before
+        *          changing. But only if the passed image is not the same as the old
+        *          one.
+        */
+       public void setImage(ObservableImage image, boolean disposeOld) {
+               if (this.image != image) {
+                       if (this.image != null && disposeOld) {
+                               this.image.dispose();
+                       }
+                       setImage(image);
+               }
+       }
+       
+       
+       /**
+        * Returns the current zoom level, which will always be between MIN_ZOOM and
+        * MAX_ZOOM. A zoom level of 1.0 is the original size.
+        * 
+        * @return The zoom level.
+        */
+       public float getZoom() {
+               return scale;
+       }
+       
+       
+       /**
+        * Set the zoom level. The value given must be between MIN_ZOOM and MAX_ZOOM.
+        * If the zoom level is different from the current zoom level, the zoom level
+        * is updated and the image is repainted at the new zoom level.
+        * 
+        * @param zoom
+        *          The zoom level to set.
+        */
+       public void setZoom(float zoom) {
+               if (this.scale != zoom) {
+                       if (zoom < MIN_ZOOM) {
+                               throw new IllegalArgumentException("zoom < MIN_ZOOM");
+                       }
+                       
+                       if (zoom > MAX_ZOOM) {
+                               throw new IllegalArgumentException("zoom > MAX_ZOOM");
+                       }
+                       
+                       disposeScaledImage();
+                       this.scale = zoom;
+                       
+                       repaint();
+                       
+                       // Notify listeners
+                       fireZoomChanged();
+               }
+       }
+       
+       
+       /**
+        * Returns the current zoom step, i.e. the amount of zoom change that will be
+        * caused by a zoom in or zoom out operation.
+        * 
+        * @return The current zoom step.
+        */
+       public float getZoomStep() {
+               return scaleStep;
+       }
+       
+       
+       /**
+        * Set the current zoom step, i.e. the amount of zoom change that will be
+        * caused by a zoom in or zoom out operation.
+        * 
+        * @param zoomStep
+        *          The new zoom step (must be {@code > 0}).
+        */
+       public void setZoomStep(float zoomStep) {
+               if (zoomStep < 0) {
+                       throw new IllegalArgumentException("zoomStep < 0");
+               }
+               
+               this.scaleStep = zoomStep;
+       }
+       
+       
+       /**
+        * Zoom in using the current zoom step. This method will never allow the zoom
+        * to be greater than MAX_ZOOM.
+        */
+       public void zoomIn() {
+               if (image != null) {
+                       float zoom = Math.min(MAX_ZOOM, scale + scaleStep);
+                       setZoom(zoom);
+               }
+       }
+       
+       
+       /**
+        * Zoom in using the current zoom step. This method will never allow the zoom
+        * to be less than MIN_ZOOM.
+        */
+       public void zoomOut() {
+               if (image != null) {
+                       float zoom = Math.max(MIN_ZOOM, scale - scaleStep);
+                       setZoom(zoom);
+               }
+       }
+       
+       
+       /**
+        * Zoom the image back to it's original size.
+        */
+       public void zoomOriginal() {
+               setZoom(1.0f);
+       }
+       
+       
+       /**
+        * Zoom the image to it's best fit inside the currently visible scroll area.
+        * The aspect ratio is maintained.
+        */
+       public void zoomBestFit() {
+               if (image != null) {
+                       float zoom = getBestFitScale();
+                       setZoom(zoom);
+               }
+       }
+
+
+       /**
+        * Returns <code>true</code> if calling {@link ImageControl#zoomIn()} will have
+        * an effect.
+        * 
+        * @return <code>true</code> if zooming in is possible.
+        */
+       public boolean canZoomIn() {
+               if (image != null) {
+                       float zoom = Math.min(MAX_ZOOM, scale + scaleStep);
+                       return zoom != scale;
+               }
+               return false;
+       }
+       
+       
+       /**
+        * Returns <code>true</code> if calling {@link ImageControl#zoomOut()} will
+        * have an effect.
+        * 
+        * @return <code>true</code> if zooming out is possible.
+        */
+       public boolean canZoomOut() {
+               if (image != null) {
+                       float zoom = Math.max(MIN_ZOOM, scale - scaleStep);
+                       return zoom != scale;
+               }
+               return false;
+       }
+       
+       
+       /**
+        * Returns <code>true</code> if calling {@link ImageControl#zoomOriginal()}
+        * will have an effect.
+        * 
+        * @return <code>true</code> if zooming to the original size will change the
+        *         zoom level.
+        */
+       public boolean canZoomOriginal() {
+               if (image != null) {
+                       return scale != 1.0;
+               }
+               return false;
+       }
+       
+       
+       /**
+        * Returns <code>true</code> if calling {@link ImageControl#zoomBestFit()} will
+        * have an effect.
+        * 
+        * @return <code>true</code> if zooming to the "best-fit" will change the
+        *         zoom level.
+        */
+       public boolean canZoomBestFit() {
+               if (image != null) {
+                       return scale != getBestFitScale();
+               }
+               return false;
+       }
+       
+       
+       /**
+        * Force the visible canvas area to repaint itself.
+        */
+       public void repaint() {
+               recomputeBounds();
+               Rectangle r = getVisibleCanvasArea();
+               canvas.redraw(r.x, r.y, r.width, r.height, false);
+       }
+       
+       
+       /**
+        * Force the given part of the image to repaint itself. The image rectangle is
+        * automatically scaled and translated to canvas coordinates. If the image is
+        * <code>null</code>, then the function does nothing.
+        * 
+        * @param part
+        *          The part of the image repaint.
+        */
+       public void repaint(Rectangle part) {
+               if (image != null) {
+                       recomputeBounds();
+                       Rectangle canv = imageToCanvas(part);
+                       Rectangle clip = getVisibleCanvasArea().intersection(canv);
+                       canvas.redraw(clip.x, clip.y, clip.width, clip.height, false);
+               }
+       }
+       
+       
+       /**
+        * Returns {@code true} if the given point on the canvas is contained within
+        * the area covered by the image displayed on the canvas. If there is no
+        * image, returns {@code false}
+        * 
+        * @param canvasPt
+        *          A point in canvas coordinates.
+        * @return <code>true</code> if contained in the image.
+        */
+       public boolean imageContains(Point canvasPt) {
+               if (image != null) {
+                       return bounds.contains(canvasPt);
+               }
+               return false;
+       }
+       
+       
+       
+       /**
+        * Translate a point on the canvas to it's corresponding point on the image
+        * currently that is displayed on the canvas. If there is no current image
+        * set, an {@code IllegalStateException} is thrown. The returned point is at
+        * the original image's scale.
+        * 
+        * @param pt
+        *          The point to translate.
+        * @return The corresponding point on the image.
+        */
+       public Point canvasToImage(Point pt) {
+               checkHaveImage();
+                               
+         // translate to image (0,0)
+               int x = pt.x - bounds.x; 
+               int y = pt.y - bounds.y;
+               
+               // scale
+               x = (int) Math.floor(x / scale);
+               y = (int) Math.floor(y / scale);
+               
+               return new Point(x, y);
+       }
+       
+       
+       /**
+        * Translate a point on the displayed image (at it's original scale) to the
+        * corresponding point on the canvas. If there is no current image set, an
+        * {@code IllegalStateException} is thrown. 
+        * 
+        * @param pt
+        *          The point on the canvas.
+        * @return The corresponding point on the image.
+        */
+       public Point imageToCanvas(Point pt) {
+               checkHaveImage();
+
+               // scale
+               int x = (int) Math.floor(pt.x * scale);
+               int y = (int) Math.floor(pt.y * scale);
+       
+               // translate
+               x += bounds.x;
+               y += bounds.y;
+               
+               return new Point(x, y);
+       }
+       
+       
+       /**
+        * Translates a rectangle on the image to a rectangle on the canvas. If there
+        * is no current image set, an {@code IllegalStateException} is thrown. If the
+        * given rectangle lies outside the image, only the part that lies inside the
+        * canvas image bounds is returned (the intersection). If it is completely
+        * outside the canvas image bounds, an empty rectangle is returned.
+        * 
+        * @param rect
+        *          The rectangle to translate.
+        * @return The translated rectangle.
+        */
+       public Rectangle imageToCanvas(Rectangle rect) {
+               checkHaveImage();
+               
+               int x = (int) Math.floor(rect.x * scale) + bounds.x;
+               int y = (int) Math.floor(rect.y * scale) + bounds.y;
+               int w = (int) Math.floor(rect.width * scale);
+               int h = (int) Math.floor(rect.height * scale); 
+               
+               return new Rectangle(x, y, w, h).intersection(bounds);
+       }
+       
+       
+       /**
+        * Translate a rectangle on the canvas to a rectangle on the image. If there
+        * is no current image set, an {@code IllegalStateException} is thrown.
+        * 
+        * @param rect
+        *          The rectangle to translate.
+        * @return The translated rectangle.
+        */
+       public Rectangle canvasToImage(Rectangle rect) {
+               checkHaveImage();
+               
+               int x = (int) Math.floor((rect.x - bounds.x) / scale);
+               int y = (int) Math.floor((rect.y - bounds.y) / scale);
+               int w = (int) Math.floor(rect.width / scale);
+               int h = (int) Math.floor(rect.height / scale); 
+               
+               return new Rectangle(x, y, w, h);
+       }
+       
+       
+       /**
+        * Get the canvas that the image is drawn on.
+        * 
+        * @return The canvas.
+        */
+       public Canvas getCanvas() {
+               return canvas;
+       }
+       
+       
+       /**
+        * Convenience method to set the canvas background color.
+        * 
+        * @param color
+        *          The color to set.
+        */
+       public void setCanvasBackground(Color color) {
+               canvas.setBackground(color);
+       }
+
+
+
+       /**
+        * Returns the bounds of the original image, or <code>null</code> if there
+        * is no image.
+        * 
+        * @return The bounding rectangle of the image, or <code>null</code>.
+        */
+       public Rectangle getImageBounds() {
+               
+               if (cachedImageBounds == null) {
+                       if (image != null) {
+                               cachedImageBounds = image.getBounds();
+                       }
+               }
+               return cachedImageBounds;
+       }
+       
+       
+       /**
+        * Returns the bounds of the image, as currently displayed on the canvas. This
+        * is the original image bounds, translated and scaled onto the image canvas.
+        * Returns <code>null</code> if there is no set image.
+        * 
+        * @return The canvas image bounds, or <code>null</code>.
+        */
+       public Rectangle getCanvasImageBounds() {
+               return bounds;
+       }
+       
+       
+       /**
+        * Add a zoom listener.
+        * 
+        * @param listener
+        *          The listener to add.
+        */
+       public void addZoomListener(ZoomListener listener) {
+               listeners.add(listener);
+       }
+       
+       
+       /**
+        * Remove a zoom listener.
+        * 
+        * @param listener
+        *          The listener to remove.
+        */
+       public void removeZoomListener(ZoomListener listener) {
+               listeners.remove(listener);
+       }
+       
+       
+       /**
+        * Dispose of the old scaled image (hence invalidating it).
+        */
+       public void disposeScaledImage() {
+               if (scaled != null) {
+                       if (!scaled.isDisposed()) {
+                               scaled.dispose();
+                       }
+                       scaled = null;
+               }
+       }
+       
+       
+       
+       /**
+        * Returns the scale of the "best-fit" for the currently visible scroll area,
+        * maintaining the aspect ratio and staying within the MAX_ZOOM and MIN_ZOOM
+        * bounds.
+        * 
+        * @return The best fit scale.
+        */
+       private float getBestFitScale() {
+               Rectangle client = scroller.getClientArea();
+               Rectangle imrect = getImageBounds();
+       
+               float sx = client.width / (float) imrect.width;
+               float sy = client.height / (float) imrect.height;
+               
+               float zoom = Math.min(sx, sy);
+               if (zoom > MAX_ZOOM) zoom = MAX_ZOOM;
+               if (zoom < MIN_ZOOM) zoom = MIN_ZOOM;
+               return zoom;
+       }
+
+
+       /**
+        * Disposes of any old scaled image and constructs a new one.
+        */
+       private void createScaledImage() {
+               disposeScaledImage();
+               
+               if (hasImage()) {
+                       recomputeBounds();
+                       
+                       scaled = new Image(getDisplay(), bounds.width, bounds.height);
+                       
+                       GC gc = new GC(scaled);
+                       
+                       Rectangle r = getImageBounds();
+                       gc.drawImage(image.getImage(), 
+                                       0, 0, r.width, r.height, 
+                                       0, 0, bounds.width, bounds.height
+                       );
+                       
+                       gc.dispose();
+               }
+       }
+
+
+       /**
+        * Computes and returns the region on the canvas that is currently visible
+        * in the scroll pane.
+        * 
+        * @return The visible canvas area.
+        */
+       private Rectangle getVisibleCanvasArea() {
+               Rectangle clip = scroller.getClientArea();
+               Point scrollPos = getScrollbarPosition();
+               clip.x += scrollPos.x;
+               clip.y += scrollPos.y;
+               return clip;
+       }
+       
+
+       /**
+        * Get the horizontal and vertical scroll-bar positions.
+        * 
+        * @return the scroll-bar position.
+        */
+       private Point getScrollbarPosition() {
+               int sx = scroller.getHorizontalBar().getSelection();
+               int sy = scroller.getVerticalBar().getSelection();
+               return new Point(sx, sy);
+       }
+       
+
+       /**
+        * Recompute the canvas image bounds and update the scroll bars.
+        */
+       private void recomputeBounds() {
+               
+               if (image == null) {
+                       // No image
+                       scroller.setMinSize(0,0);
+                       bounds.x = bounds.y = 0;
+                       bounds.width = bounds.height = 0;
+                       return;
+               }
+               
+               Rectangle imrect = getImageBounds();
+               Rectangle area = scroller.getClientArea();
+               
+               // Scale image width and height
+               bounds.width = (int) (imrect.width * scale);
+               bounds.height = (int) (imrect.height * scale);
+               
+               // Center image horizontally
+               if (bounds.width < area.width) {
+                       int dx = area.width - bounds.width;
+                       bounds.x = dx / 2; 
+               } else {
+                       bounds.x = 0;
+               }
+               
+               // Center image vertically
+               if (bounds.height < area.height) {
+                       int dy = area.height - bounds.height;
+                       bounds.y = dy / 2;
+               } else {
+                       bounds.y = 0;
+               }
+               
+               // Configure scroll bars
+               scroller.setMinSize(bounds.width, bounds.height);
+       }
+       
+       
+       /**
+        * Returns <code>true</code> if we have an up to date copy of a properly
+        * scaled version of the image.
+        * 
+        * @return <code>true</code> if a scaled image is available.
+        */
+       private boolean hasScaledImage() {
+               return scaled != null && !scaled.isDisposed();
+       }
+       
+       
+       /**
+        * Throws an {@code IllegalStateException} if there is no image.
+        */
+       private void checkHaveImage() {
+               if (image == null) {
+                       throw new IllegalStateException("image == null");
+               }
+       }
+       
+       
+       /**
+        * Fire a zoom changed event.
+        */
+       private void fireZoomChanged() {
+               ZoomEvent evt = null;
+               for (ZoomListener z : listeners) {
+                       if (evt == null) {
+                               evt = new ZoomEvent(this);
+                       }
+                       z.zoomChanged(evt);
+               }
+       }
+       
+       
+       private ImageListener imageListener = new ImageListener() {
+               public void imageChanged(ImageEvent e) {
+                       handleImageChanged(e);
+               }
+       };
+       
+}
diff --git a/Annotation/src/ie/dcu/swt/ImageConverter.class b/Annotation/src/ie/dcu/swt/ImageConverter.class
new file mode 100644 (file)
index 0000000..ef75a11
Binary files /dev/null and b/Annotation/src/ie/dcu/swt/ImageConverter.class differ
diff --git a/Annotation/src/ie/dcu/swt/ImageConverter.java b/Annotation/src/ie/dcu/swt/ImageConverter.java
new file mode 100644 (file)
index 0000000..ccb037f
--- /dev/null
@@ -0,0 +1,172 @@
+package ie.dcu.swt;
+
+import java.awt.image.*;
+
+import org.eclipse.swt.graphics.*;
+
+/**
+ * Converts SWT ImageData objects to BufferedImage objects and vice-versa.
+ * 
+ * @author Kevin McGuinness
+ */
+public class ImageConverter {
+       
+       public static BufferedImage convert(ImageData data) {
+               ColorModel cm = null;
+               PaletteData palette = data.palette;
+               
+               if (palette.isDirect) {
+                       cm = new DirectColorModel(
+                                       data.depth, 
+                                       palette.redMask, 
+                                       palette.greenMask,
+                                       palette.blueMask
+                       );
+                       
+                       WritableRaster raster = cm.createCompatibleWritableRaster(
+                                       data.width, data.height);
+                       
+                       BufferedImage im = new BufferedImage(cm, raster, false, null);
+                       
+                       int[] pixels = new int[3];
+                       for (int y = 0; y < data.height; y++) {
+                               for (int x = 0; x < data.width; x++) {
+                                       int pixel = data.getPixel(x, y);
+                                       RGB rgb = palette.getRGB(pixel);
+                                       pixels[0] = rgb.red;
+                                       pixels[1] = rgb.green;
+                                       pixels[2] = rgb.blue;
+                                       raster.setPixels(x, y, 1, 1, pixels);
+                               }
+                       }
+                       return im;
+                       
+               } else {
+                       
+                       RGB[] rgbs = palette.getRGBs();
+                       byte[] red = new byte[rgbs.length];
+                       byte[] green = new byte[rgbs.length];
+                       byte[] blue = new byte[rgbs.length];
+                       
+                       for (int i = 0; i < rgbs.length; i++) {
+                               RGB rgb = rgbs[i];
+                               red[i] = (byte) rgb.red;
+                               green[i] = (byte) rgb.green;
+                               blue[i] = (byte) rgb.blue;
+                       }
+                       
+                       if (data.transparentPixel != -1) {
+                               cm = new IndexColorModel(
+                                               data.depth, 
+                                               rgbs.length, 
+                                               red, green, blue,
+                                               data.transparentPixel
+                               );
+                               
+                       } else {
+                               cm = new IndexColorModel(
+                                               data.depth, 
+                                               rgbs.length, 
+                                               red, green, blue
+                               );
+                       }
+                       
+                       WritableRaster raster = cm.createCompatibleWritableRaster(
+                                       data.width, data.height);
+                       
+                       BufferedImage im = new BufferedImage(cm,
+                                       raster, false, null);
+                       
+                       int[] pixels = new int[1];
+                       for (int y = 0; y < data.height; y++) {
+                               for (int x = 0; x < data.width; x++) {
+                                       int pixel = data.getPixel(x, y);
+                                       pixels[0] = pixel;
+                                       raster.setPixel(x, y, pixels);
+                               }
+                       }
+                       
+                       return im;
+               }
+       }
+
+
+       public static ImageData convertToSWT(BufferedImage im) {
+               
+               ColorModel cm = im.getColorModel();
+               
+               if (cm instanceof DirectColorModel) {
+                       DirectColorModel dcm = (DirectColorModel) cm;
+                       
+                       PaletteData palette = new PaletteData(
+                                       dcm.getRedMask(), 
+                                       dcm.getGreenMask(),
+                                       dcm.getBlueMask()
+                       );
+                       
+                       ImageData data = new ImageData(
+                                       im.getWidth(), im.getHeight(),
+                                       dcm.getPixelSize(), palette
+                       );
+                       
+                       WritableRaster raster = im.getRaster();
+                       
+                       int[] pixels = new int[3];
+                       RGB rgb = new RGB(0,0,0);
+                       
+                       for (int y = 0; y < data.height; y++) {
+                               for (int x = 0; x < data.width; x++) {
+                                       raster.getPixel(x, y, pixels);
+                                       rgb.red   = pixels[0];
+                                       rgb.green = pixels[1];
+                                       rgb.blue  = pixels[2];
+                                       int pixel = palette.getPixel(rgb);
+                                       data.setPixel(x, y, pixel);
+                               }
+                       }
+                       
+                       return data;
+                       
+                       
+               } else if (cm instanceof IndexColorModel) {
+                       IndexColorModel icm = (IndexColorModel) cm;
+                       
+                       int size = icm.getMapSize();
+                       byte[] reds = new byte[size];
+                       byte[] greens = new byte[size];
+                       byte[] blues = new byte[size];
+                       
+                       icm.getReds(reds);
+                       icm.getGreens(greens);
+                       icm.getBlues(blues);
+                       
+                       RGB[] rgbs = new RGB[size];
+                       for (int i = 0; i < rgbs.length; i++) {
+                               rgbs[i] = new RGB(reds[i] & 0xFF, greens[i] & 0xFF, blues[i] & 0xFF);
+                       }
+                       
+                       PaletteData palette = new PaletteData(rgbs);
+                       
+                       ImageData data = new ImageData(
+                                       im.getWidth(), im.getHeight(),
+                                       icm.getPixelSize(), palette
+                       );
+                       
+                       
+                       data.transparentPixel = icm.getTransparentPixel();
+                       WritableRaster raster = im.getRaster();
+                       
+                       int[] pixels = new int[1];
+                       for (int y = 0; y < data.height; y++) {
+                               for (int x = 0; x < data.width; x++) {
+                                       raster.getPixel(x, y, pixels);
+                                       data.setPixel(x, y, pixels[0]);
+                               }
+                       }
+                       
+                       return data;
+               }
+               
+               return null;
+       }
+}
diff --git a/Annotation/src/ie/dcu/swt/MatrixVisualizer.class b/Annotation/src/ie/dcu/swt/MatrixVisualizer.class
new file mode 100644 (file)
index 0000000..865e373
Binary files /dev/null and b/Annotation/src/ie/dcu/swt/MatrixVisualizer.class differ
diff --git a/Annotation/src/ie/dcu/swt/MatrixVisualizer.java b/Annotation/src/ie/dcu/swt/MatrixVisualizer.java
new file mode 100644 (file)
index 0000000..ba12aa8
--- /dev/null
@@ -0,0 +1,74 @@
+package ie.dcu.swt;
+
+import ie.dcu.image.colormap.*;
+import ie.dcu.matrix.*;
+
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.PaletteData;
+
+/**
+ * Visualize matrices using color maps.
+ * 
+ * @author Kevin McGuinness
+ */
+public class MatrixVisualizer {
+
+       private ColorMap colorMap;
+       
+       public MatrixVisualizer() {
+               this(ColorMaps.hot());
+       }
+       
+       public MatrixVisualizer(ColorMap map) {
+               setColorMap(map);
+       }
+       
+       public ColorMap getColorMap() {
+               return colorMap;
+       }
+
+       public void setColorMap(ColorMap map) {
+               if (map == null) {
+                       throw new IllegalArgumentException("colorMap == null");
+               }
+               this.colorMap = map;
+       }
+
+       public ImageData createVisualization(Matrix matrix) {
+               return visualize(matrix.toDoubleMatrix());
+       }
+       
+       private ImageData visualize(DoubleMatrix matrix) {
+               rescale(matrix);
+               PaletteData palette = colorMap.createPaletteData();
+               ImageData image = new ImageData(matrix.cols, matrix.rows, 8, palette);
+               
+               int n = colorMap.size();
+               
+               for (int i = 0; i < matrix.rows; i++) {
+                       int k = i * matrix.cols;
+
+                       for (int j = 0; j < matrix.cols; j++, k++) {
+                               int value = (int) (matrix.values[k] * (n-1));
+                               image.setPixel(j, i, value);
+                       }
+               }
+               
+               return image;
+       }
+       
+       private void rescale(DoubleMatrix matrix) {
+               
+               double min = matrix.minValue();
+               double max = matrix.maxValue();
+               double range = max - min;
+               
+               if (range == 0) {
+                       range = 1;
+               }
+
+               for (int i = 0; i < matrix.size; i++) {         
+                       matrix.values[i] = (matrix.values[i] + min) / range;
+               }
+       }
+}
diff --git a/Annotation/src/ie/dcu/swt/ObservableImage.class b/Annotation/src/ie/dcu/swt/ObservableImage.class
new file mode 100644 (file)
index 0000000..071b336
Binary files /dev/null and b/Annotation/src/ie/dcu/swt/ObservableImage.class differ
diff --git a/Annotation/src/ie/dcu/swt/ObservableImage.java b/Annotation/src/ie/dcu/swt/ObservableImage.java
new file mode 100644 (file)
index 0000000..fd002ab
--- /dev/null
@@ -0,0 +1,187 @@
+package ie.dcu.swt;
+
+import ie.dcu.swt.event.*;
+
+import java.util.*;
+
+import org.eclipse.swt.graphics.*;
+
+public class ObservableImage {
+       private final List<ImageListener> listeners;
+       private Image image;
+       private ImageData data;
+       private Rectangle modified;
+       private GC gc;
+       private int refCount;
+       private boolean suspendNotifications;
+
+       
+       public ObservableImage(Image image) {
+               this.listeners = new ArrayList<ImageListener>(2);
+               this.image = image;
+       }
+       
+       
+       public GC beginPaint() {
+               if (refCount > 0) {
+                       refCount++;
+                       return gc;              
+               } else {
+                       modified = null;
+                       refCount = 1;
+                       return (gc = new GC(image));
+               }       
+       }
+
+       
+       public void endPaint() {
+               endPaint(null);
+       }
+       
+       
+       public void endPaint(Rectangle modified) {
+               refCount--;
+               if (refCount < 0) {
+                       throw new IllegalStateException();
+               }
+
+               updateModified(modified);
+
+               if (refCount == 0) {
+                       data = null;
+                       gc.dispose();
+                       gc = null;              
+                       fireImageChanged();
+               }
+       }
+       
+       
+       public Image getImage() {
+               return image;
+       }
+       
+       
+       public ImageData getImageData() {
+               if (data == null) {
+                       data = image.getImageData();
+               }
+               return data;
+       }
+       
+       
+       public void setImage(Image image, boolean disposeOld) {
+               if (gc != null) {
+                       throw new IllegalStateException();
+               }
+               
+               if (image == null) {
+                       throw new NullPointerException();
+               }
+               
+               boolean dimensionsChanged = false;
+               if (this.image != null && !this.image.isDisposed()) {
+                       Rectangle oldBounds = this.image.getBounds();
+                       Rectangle newBounds = image.getBounds();
+                       
+                       dimensionsChanged = !oldBounds.equals(newBounds);
+               } else {
+                       dimensionsChanged = true;
+               }
+               
+               if (disposeOld) {
+                       dispose();
+               }
+               
+               this.image = image;
+               
+               // Invalidate cached image data
+               this.data = null;
+               fireImageChanged(dimensionsChanged);
+       }
+       
+
+
+       public void setSuspendNotifications(boolean suspend) {
+               this.suspendNotifications = suspend;
+       }
+
+
+       public boolean isDisposed() {
+               if (image != null) {
+                       return image.isDisposed();
+               }
+               return false;
+       }
+       
+       
+       public void dispose() {
+               if (image != null && !image.isDisposed()) {
+                       image.dispose();
+               }
+               data = null;
+       }
+       
+
+       public Rectangle getBounds() {
+               return image.getBounds();       
+       }
+       
+       
+       public Rectangle getModifiedArea() {
+               return modified;
+       }
+       
+       
+       public void addImageListener(ImageListener listener) {
+               listeners.add(listener);
+       }
+       
+       
+       public void removeImageListener(ImageListener listener) {
+               listeners.remove(listener);
+       }
+       
+       
+       public void fireImageChanged() {
+               fireImageChanged(getModifiedArea(), false);
+       }
+       
+       
+       public void fireImageChanged(Rectangle modified) {
+               fireImageChanged(modified, false);
+       }
+       
+       
+       private void fireImageChanged(boolean dimensionsChanged) {
+               fireImageChanged(getModifiedArea(), dimensionsChanged);
+       }
+               
+
+       private void fireImageChanged(Rectangle modified, boolean dimensionsChanged) {
+               if (suspendNotifications) {
+                       return;
+               }
+               
+               ImageEvent e = null;
+               for (ImageListener i : listeners) {
+                       if (e == null) {
+                               e = new ImageEvent(this, modified, dimensionsChanged);
+                       }
+                       i.imageChanged(e);
+               }
+       }
+
+
+       private void updateModified(Rectangle m) {
+               if (m == null) {
+                       this.modified = image.getBounds();
+               } else {
+                       if (this.modified != null) {
+                               this.modified = this.modified.union(m);
+                       } else {
+                               this.modified = SwtUtils.clone(m);
+                       }
+               }
+       }
+}
+
diff --git a/Annotation/src/ie/dcu/swt/PopupComposite$1.class b/Annotation/src/ie/dcu/swt/PopupComposite$1.class
new file mode 100644 (file)
index 0000000..0e43546
Binary files /dev/null and b/Annotation/src/ie/dcu/swt/PopupComposite$1.class differ
diff --git a/Annotation/src/ie/dcu/swt/PopupComposite$ActivationListener.class b/Annotation/src/ie/dcu/swt/PopupComposite$ActivationListener.class
new file mode 100644 (file)
index 0000000..f215e2f
Binary files /dev/null and b/Annotation/src/ie/dcu/swt/PopupComposite$ActivationListener.class differ
diff --git a/Annotation/src/ie/dcu/swt/PopupComposite.class b/Annotation/src/ie/dcu/swt/PopupComposite.class
new file mode 100644 (file)
index 0000000..3e06dc4
Binary files /dev/null and b/Annotation/src/ie/dcu/swt/PopupComposite.class differ
diff --git a/Annotation/src/ie/dcu/swt/PopupComposite.java b/Annotation/src/ie/dcu/swt/PopupComposite.java
new file mode 100644 (file)
index 0000000..90ba969
--- /dev/null
@@ -0,0 +1,200 @@
+package ie.dcu.swt;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+
+
+/**
+ * Class for displaying a pop-up control in its own shell. The control behaves
+ * similar to a pop-up menu, but is a composite so can contain arbitrary
+ * controls.
+ * 
+ * <p>
+ * <b>Sample Usage:</b>
+ * 
+ * <pre>
+ * PopupComposite popup = new PopupComposite(getShell());
+ * Text text = new Text(popup, SWT.BORDER);
+ * popup.pack();
+ * popup.show(shell.toDisplay(new Point(10, 10)));
+ * </pre>
+ * 
+ * @author Kevin McGuinness
+ */
+public class PopupComposite extends Composite {
+       
+       
+       /**
+        * Style of the shell that will house the composite
+        */ 
+       private static final int SHELL_STYLE = 
+               SWT.MODELESS | SWT.NO_TRIM | SWT.ON_TOP | SWT.BORDER;
+       
+       
+       /**
+        * Shell that will house the composite
+        */ 
+       private final Shell shell;
+       
+       
+       /**
+        * Create a Pop-up composite with the default {@link SWT#BORDER} style.
+        * 
+        * @param parent
+        *          The parent shell.
+        */
+       public PopupComposite(Shell parent) {
+               this(parent, SWT.BORDER);
+       }
+       
+       
+       /**
+        * Create a Pop-up composite. The default layout is a fill layout.
+        * 
+        * @param parent
+        *          The parent shell.
+        * @param style
+        *          The composite style.
+        */
+       public PopupComposite(Shell parent, int style) {
+               super(new Shell(parent, SHELL_STYLE), style);
+               shell = getShell();
+               shell.setLayout(new FillLayout());;
+               shell.addShellListener(new ActivationListener());
+               setLayout(createLayout());
+       }
+
+       
+       /**
+        * Display the composite below the given tool item. The item will be sized
+        * such that it's width is at least the width of the given tool item.
+        * 
+        * @param bar
+        *          The tool bar.
+        * @param item
+        *          The tool item.
+        */
+       public void showBelow(ToolBar bar, ToolItem item) {
+               Rectangle r = item.getBounds();
+               Point p = bar.toDisplay(new Point(r.x, r.y + r.height));
+               setSize(computeSize(item));
+               show(p);
+       }
+       
+       
+       /**
+        * Display the composite in its own shell at the given point.
+        * 
+        * @param pt
+        *          The point where the pop-up should appear.
+        */
+       public void show(Point pt) {
+               // Match shell and component sizes
+               shell.setSize(getSize());
+               
+               if (pt != null) {
+                       shell.setLocation(pt);
+               }
+               
+               shell.open();
+       }
+       
+       
+       /**
+        * Display the pop-up where it was last displayed.
+        */
+       public void show() {
+               show(null);
+       }
+       
+       
+       /**
+        * Hide the pop-up.
+        */
+       public void hide() {
+               shell.setVisible(false);
+       }
+       
+       
+       /**
+        * Returns <code>true</code> if the shell is currently activated.
+        * 
+        * @return <code>true</code> if the shell is visible.
+        */
+       public boolean isDisplayed() {
+               return shell.isVisible();
+       }
+       
+
+       /**
+        * Creates the default layout for the composite.
+        * 
+        * @return the default layout.
+        */
+       private FillLayout createLayout() {
+               FillLayout layout = new FillLayout();
+               layout.marginWidth = 5;
+               layout.marginHeight = 5;
+               return layout;
+       }
+
+       
+       /**
+        * Computes the optimal size with respect to the given tool item.
+        * 
+        * @param item
+        *          The tool item.
+        * @return The optimal size.
+        */
+       private Point computeSize(ToolItem item) {
+               Point s2 = computeSize(item.getWidth(), SWT.DEFAULT);
+               Point s1 = computeSize(SWT.DEFAULT, SWT.DEFAULT);
+               return s1.x > s2.x ? s1 : s2;
+       }
+       
+
+       /**
+        * Class that handles shell appearance and disappearance appropriately.
+        * Specifically, it hides the shell when it becomes de-activated (for example,
+        * when the user clicks on the parent shell). Also, there is a minimum delay
+        * which is enforced between showing and hiding the pop-up, to prevent
+        * undesirable behavior such as hiding and immediately re-displaying the
+        * pop-up when the user selects a button responsible for showing the tool
+        * item.
+        */
+       private final class ActivationListener extends ShellAdapter {
+               private static final int TIMEOUT = 500;
+               private long time = -1;
+
+
+               @Override
+               public void shellDeactivated(ShellEvent e) {
+                       // Record time of event
+                       time = (e.time & 0xFFFFFFFFL);
+                       
+                       // Hide
+                       hide();
+               }
+
+
+               @Override
+               public void shellActivated(ShellEvent e) {
+                       if (time > 0) {
+                               // Find elapsed time 
+                               long elapsed = ((e.time & 0xFFFFFFFFL) - time);
+                               
+                               // If less than a timeout, don't activate
+                               if (elapsed < TIMEOUT) {
+                                       hide();
+                                       
+                                       // Next activation event is fine
+                                       time = -1;
+                               }
+                       }
+               }
+       };
+       
+}
\ No newline at end of file
diff --git a/Annotation/src/ie/dcu/swt/SwtUtils$1.class b/Annotation/src/ie/dcu/swt/SwtUtils$1.class
new file mode 100644 (file)
index 0000000..43392ad
Binary files /dev/null and b/Annotation/src/ie/dcu/swt/SwtUtils$1.class differ
diff --git a/Annotation/src/ie/dcu/swt/SwtUtils$Pt.class b/Annotation/src/ie/dcu/swt/SwtUtils$Pt.class
new file mode 100644 (file)
index 0000000..e350637
Binary files /dev/null and b/Annotation/src/ie/dcu/swt/SwtUtils$Pt.class differ
diff --git a/Annotation/src/ie/dcu/swt/SwtUtils$Rect.class b/Annotation/src/ie/dcu/swt/SwtUtils$Rect.class
new file mode 100644 (file)
index 0000000..6ba7425
Binary files /dev/null and b/Annotation/src/ie/dcu/swt/SwtUtils$Rect.class differ
diff --git a/Annotation/src/ie/dcu/swt/SwtUtils.class b/Annotation/src/ie/dcu/swt/SwtUtils.class
new file mode 100644 (file)
index 0000000..f00e9a5
Binary files /dev/null and b/Annotation/src/ie/dcu/swt/SwtUtils.class differ
diff --git a/Annotation/src/ie/dcu/swt/SwtUtils.java b/Annotation/src/ie/dcu/swt/SwtUtils.java
new file mode 100644 (file)
index 0000000..fd1d95e
--- /dev/null
@@ -0,0 +1,857 @@
+package ie.dcu.swt;
+
+import ie.dcu.swt.event.*;
+import ie.dcu.util.FileUtils;
+
+import java.io.*;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.dnd.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+
+/**
+ * Miscellaneous SWT Utility functions.
+ * 
+ * @author Kevin McGuinness
+ */
+public class SwtUtils {
+       
+       /**
+        * Out-code TOP.
+        */
+       public static final int TOP    = java.awt.Rectangle.OUT_TOP;
+       
+       /**
+        * Out-code LEFT.
+        */
+       public static final int LEFT   = java.awt.Rectangle.OUT_LEFT;
+       
+       /**
+        * Out-code BOTTOM.
+        */
+       public static final int BOTTOM = java.awt.Rectangle.OUT_BOTTOM;
+       
+       /**
+        * Out-code RIGHT.
+        */
+       public static final int RIGHT  = java.awt.Rectangle.OUT_RIGHT;
+
+       /**
+        * Clone a rectangle.
+        */
+       public static Rectangle clone(Rectangle r) {
+               return new Rectangle(r.x, r.y, r.width, r.height);
+       }
+
+       /**
+        * Clone a point.
+        */
+       public static Point clone(Point p) {
+               return new Point(p.x, p.y);
+       }
+
+
+       /**
+        * Scale a rectangle.
+        * 
+        * @param r
+        *            The rectangle.
+        * @param scale
+        *            The scale.
+        * @return A scaled rectangle.
+        */
+       public static Rectangle scale(Rectangle r, float scale) {
+               return new Rectangle(
+                               (int) Math.floor(r.x * scale), 
+                               (int) Math.floor(r.y * scale), 
+                               (int) Math.floor(r.width * scale),
+                               (int) Math.floor(r.height * scale)
+               );
+       }
+       
+       /**
+        * Convert a SWT rectangle to an AWT rectangle.
+        * 
+        * @param r
+        *            An SWT Rectangle.
+        * @return An AWT Rectangle.
+        */
+       public static java.awt.Rectangle convert(Rectangle r) {
+               return new java.awt.Rectangle(r.x, r.y, r.width, r.height);
+       }
+       
+       /**
+        * Determines where the specified coordinates lie with respect to this
+        * <code>Rectangle</code>. This method computes a binary OR of the
+        * appropriate mask values indicating, for each side of this
+        * <code>Rectangle</code>, whether or not the specified coordinates are on
+        * the same side of the edge as the rest of this <code>Rectangle</code>.
+        * 
+        * @param r
+        *            A rectangle.
+        * @param p
+        *            A point.
+        * @return the logical OR of all appropriate out codes.
+        * @see #LEFT
+        * @see #TOP
+        * @see #RIGHT
+        * @see #BOTTOM
+        */
+       public static int outcode(Rectangle r, Point p) {
+               return convert(r).outcode(p.x, p.y);
+       }
+       
+       /**
+        * Determines where the specified coordinates lie with respect to this
+        * <code>Rectangle</code>. This method computes a binary OR of the
+        * appropriate mask values indicating, for each side of this
+        * <code>Rectangle</code>, whether or not the specified coordinates are on
+        * the same side of the edge as the rest of this <code>Rectangle</code>.
+        * 
+        * @param r
+        *            A rectangle. 
+        * @param x
+        *            the specified x coordinate
+        * @param y
+        *            the specified y coordinate
+        * @return the logical OR of all appropriate out codes.
+        * 
+        * @see #LEFT
+        * @see #TOP
+        * @see #RIGHT
+        * @see #BOTTOM
+        */
+       public static int outcode(Rectangle r, float x, float y){
+               return convert(r).outcode(x, y);
+       }
+       
+       
+       // Point class for Liang-Barsky algorithm
+       private static class Pt {
+               float x, y;
+               
+               Pt(float x, float y) {
+                       this.x = x; this.y = y;
+               }
+       }
+       
+       
+       // Rectangle class for Liang-Barsky algorithm
+       private static class Rect {
+               float ymin, ymax, xmin, xmax;
+               
+               Rect(float x, float y, float w, float h) {
+                       // max needs -1 otherwise its outside the rectangle!
+                       ymin = y; ymax = y + h - 1; 
+                       xmin = x; xmax = x + w - 1;
+               }
+               
+               boolean contains(Pt p) {
+                       return p.x >= xmin && p.x <= xmax && p.y >= ymin && p.y <= ymax;
+               }
+       }
+       
+       
+       // Liang-Barsky clip test method
+       private static boolean clipt(float y, float x, Pt p) {
+               if (y > 0) {
+                       float t = x / y;
+                       if (t > p.y) {
+                               return false;
+                       } else if (t > p.x) {
+                               p.x  = t;
+                       }
+               } else if (y < 0) {
+                       float t = x / y;
+                       if (t < p.x) {
+                               return false;
+                       } else if (t < p.y) {
+                               p.y = t;
+                       }
+               } else if (x > 0) {
+                       return false;
+               }
+               
+               return true;
+       }
+       
+       
+       // Liang-barsky line clipping algorithm
+       private static boolean liangBarskyClip(Rect r, Pt p, Pt q) {
+               float dx = q.x - p.x;
+               float dy = q.y - p.y;
+               
+               if (dx == 0 && dy == 0 && r.contains(p)) {
+                       return true;
+               }
+               
+               Pt t = new Pt(0, 1);
+               if (clipt(dx, r.xmin - p.x, t)) {
+                       if (clipt(-dx, p.x - r.xmax, t)) {
+                               if (clipt(dy, r.ymin - p.y, t)) {
+                                       if (clipt(-dy, p.y - r.ymax, t)) {
+                                               if (t.y < 1) {
+                                                       q.x = p.x + t.y * dx;
+                                                       q.y = p.y + t.y * dy;
+                                               }
+                                               if (t.x > 0) {
+                                                       p.x += t.x * dx;
+                                                       p.y += t.x * dy;
+                                               }
+                                               
+                                               return true;
+                                       }
+                               }
+                       }
+               }
+               
+               return false;
+       }
+       
+       
+       /**
+        * Clip a line using the Liang-Barsky line clipping algorithm.
+        * 
+        * @param r
+        *          The clipping rectangle.
+        * @param p
+        *          First point on the line segment. If the point lies outside the
+        *          clipping rectangle it will be clipped to the nearest point on the
+        *          line inside the clipping rectangle on exit.
+        * @param q
+        *          Second point on the line segment. If the point lies outside the
+        *          clipping rectangle it will be clipped to the nearest point on the
+        *          line inside the clipping rectangle on exit.
+        * 
+        * @return <code>true</code> if the line has a visible segment inside the
+        *         clipping rectangle, <code>false</code> if it is completely
+        *         outside the clipping window.
+        */
+       public static boolean clip(Rectangle r, Point p, Point q) {
+               Rect r1 = new Rect(r.x, r.y, r.width, r.height);
+               Pt p1 = new Pt(p.x, p.y);
+               Pt p2 = new Pt(q.x, q.y);
+               boolean result = liangBarskyClip(r1, p1, p2);
+               p.x = (int) p1.x;
+               p.y = (int) p1.y;
+               q.x = (int) p2.x;
+               q.y = (int) p2.y;
+               return result;
+       }
+
+       /**
+        * Clone the given SWT image.
+        * 
+        * @param image
+        *            An SWT Image.
+        * @return A newly created SWT image that is a copy of the given image.
+        */
+       public static Image clone(Image image) {
+               return new Image(Display.getCurrent(), image, SWT.IMAGE_COPY);
+       }
+       
+       /**
+        * Apply the given SWT system color as the foreground color in the given
+        * graphics context.
+        * 
+        * @param gc
+        *            The graphics context.
+        * @param swtColor
+        *            An SWT system color.
+        */
+       public static void setForeground(GC gc, int swtColor) {
+               gc.setForeground(Display.getCurrent().getSystemColor(swtColor));
+       }
+       
+       /**
+        * Apply the given SWT system color as the background color in the given
+        * graphics context.
+        * 
+        * @param gc
+        *            The graphics context.
+        * @param swtColor
+        *            An SWT system color.
+        */
+       public static void setBackground(GC gc, int swtColor) {
+               gc.setBackground(Display.getCurrent().getSystemColor(swtColor));
+       }
+       
+       /**
+        * Returns a standard RGB palette.
+        *  
+        * @return An RGB palette.
+        */
+       public static PaletteData getRgbPalette() {
+               return new PaletteData(0xff, 0xff00, 0xff0000);
+       }
+       
+       /**
+        * Create an RGB image with a transparent component, and fill the image with
+        * the transparent value.
+        * 
+        * @param width
+        *            The image width.
+        * @param height
+        *            The image height.
+        * @return A newly created Image object.
+        */
+       public static Image createTransparentImage(int width, int height) {
+               PaletteData palette = getRgbPalette();
+               
+               // Use a bit depth of 32 to allow transparent pixel outside RGB space
+               ImageData data = new ImageData(width, height, 32, palette);
+               
+               // Create a transparent pixel outside the RGB color space
+               int transparent =  palette.getPixel(new RGB(255,255,255)) + 2;
+               data.transparentPixel = transparent;
+               
+               // Create a row of transparent pixels
+               int [] pixels = new int[data.width];
+               for (int i = 0; i < pixels.length; i++) {
+                       pixels[i] = transparent;
+               }
+               
+               // Copy pixels to entire image
+               for (int y = 0; y < data.height; y++) {
+                       data.setPixels(0, y, pixels.length, pixels, 0);
+               }
+               
+               // Create and return the image
+               return new Image(Display.getCurrent(), data);
+       }
+       
+       /**
+        * Create a standard image for the current display with the given width and
+        * height.
+        * 
+        * @param w
+        *            The image width.
+        * @param h
+        *            The image height.
+        * @return A newly created Image object.
+        */
+       public static Image createImage(int w, int h) {
+               return new Image(Display.getCurrent(), w, h);
+       }
+       
+       /**
+        * Create a new image with for the current display with the size given by
+        * the width and height of the specified bounds object.
+        * 
+        * @param bounds
+        *            The image bounds.
+        * @return A newly created Image object.
+        */
+       public static Image createImage(Rectangle bounds) {
+               return createImage(bounds.width, bounds.height);
+       }
+       
+       /**
+        * Scale the given image to fit inside the specified Rectangle.
+        * 
+        * @param image
+        *            An image
+        * @param rect
+        *            The rectangle to fit to
+        * @param maintainAspectRatio
+        *            if <code>true</code> the aspect ratio of the image is
+        *            maintained.
+        * @return A newly created scaled image.
+        */
+       public static Image scaleImageToFit(Image image, 
+                       Rectangle rect, boolean maintainAspectRatio) 
+       {
+               return scaleImageToFit(image, rect.width, rect.height, 
+                               maintainAspectRatio);
+       }
+       
+       /**
+        * Scale the given image to fit inside the specified height and width.
+        * 
+        * @param image
+        *            An image
+        * @param width
+        *            The width
+        * @param height
+        *            The height
+        * @param maintainAspectRatio
+        *            if <code>true</code> the aspect ratio of the image is
+        *            maintained.
+        * @return A newly created scaled image.
+        */
+       public static Image scaleImageToFit(Image image, 
+                       int width, int height, boolean maintainAspectRatio) 
+       {
+               ImageData data = image.getImageData();
+               data = scaleImageDataToFit(data, width, height, maintainAspectRatio);
+               return new Image(image.getDevice(), data);
+       }
+       
+       /**
+        * Scale the given ImageData to fit inside the specified Rectangle.
+        * 
+        * @param data
+        *            A non-null ImageData object
+        * @param rect
+        *            The rectangle to fit to
+        * @param maintainAspectRatio
+        *            if <code>true</code> the aspect ratio of the image is
+        *            maintained.
+        * @return A scaled ImageData object.
+        */
+       public static ImageData scaleImageDataToFit(ImageData data, 
+                       Rectangle rect, boolean maintainAspectRatio) 
+       {
+               return scaleImageDataToFit(data, rect.width, rect.height, 
+                               maintainAspectRatio);
+       }
+       
+       /**
+        * Scale the given ImageData to fit inside the specified height and width.
+        * 
+        * @param data
+        *            A non-null ImageData object
+        * @param width
+        *            The width to fit to
+        * @param height
+        *            The height to fit to
+        * @param maintainAspectRatio
+        *            if <code>true</code> the aspect ratio of the image is
+        *            maintained.
+        * @return A scaled ImageData object.
+        */
+       public static ImageData scaleImageDataToFit(ImageData data, 
+                       int width, int height, boolean maintainAspectRatio) 
+       {
+               if (width <= 0) {
+                       throw new IllegalArgumentException("width <= 0");
+               }
+               
+               if (height <= 0) {
+                       throw new IllegalArgumentException("height <= 0");
+               }
+               
+               if (data == null) {
+                       throw new IllegalArgumentException("data == null");
+               }
+               
+               if (!maintainAspectRatio) {
+                       // Direct scale
+                       data = data.scaledTo(width, height);
+                       
+               } else {
+                       // Compute scale
+                       double sx = width / (double) data.width;
+                       double sy = height / (double) data.height;
+                       double scale = Math.min(sx, sy);
+                       
+                       // Compute new dimensions
+                       int newWidth  = (int) (data.width  * scale);
+                       int newHeight = (int) (data.height * scale);
+                       
+                       // Clamp dimensions
+                       newWidth  = Math.max(Math.min(newWidth, width), 1);
+                       newHeight = Math.max(Math.min(newHeight, height), 1); 
+                       
+                       // Scale
+                       data = data.scaledTo(newWidth, newHeight);
+               }
+               
+               return data;
+       }
+       
+       /**
+        * Load an image for the current display from the given file.
+        * 
+        * @param file
+        *            A file.
+        * @return A newly created image.
+        * @throws IOException
+        *             If an error occurs loading the image.
+        */
+       public static Image loadImage(File file) 
+               throws IOException 
+       {
+               try {
+                       return new Image(Display.getCurrent(), file.getAbsolutePath());
+               } catch (SWTException e) {
+                       // Translate to checked exception!
+                       throw new IOException("SWTException: " + e.getMessage());
+               }
+       }
+       
+       /**
+        * Load an image for the current display from the given InputStream.
+        * 
+        * @param in
+        *            An input stream.
+        * @return A newly created image.
+        * @throws IOException
+        *             If an error occurs loading the image.
+        */
+       public static Image loadImage(InputStream in) 
+               throws IOException
+       {
+               try {
+                       return new Image(Display.getCurrent(), in);
+               } catch (SWTException e) {
+                       // Translate to checked exception!
+                       throw new IOException("SWTException: " + e.getMessage());
+               }
+       }
+       
+       /**
+        * Load the ImageData object from the given file.
+        * 
+        * @param file
+        *            A file.
+        * @return A newly created image.
+        * @throws IOException
+        *             If an error occurs loading the image.
+        */
+       public static ImageData loadImageData(File file)
+               throws IOException
+       {
+               try {
+                       return new ImageData(file.getAbsolutePath());
+               } catch (SWTException e) {
+                       // Translate to checked exception!
+                       throw new IOException("SWTException: " + e.getMessage());
+               }
+       }
+       
+       /**
+        * Load the ImageData object from the given InputStream.
+        * 
+        * @param in
+        *            An input stream.
+        * @return A newly created image.
+        * @throws IOException
+        *             If an error occurs loading the image.
+        */
+       public static ImageData loadImageData(InputStream in) 
+               throws IOException 
+       {
+               try {
+                       return new ImageData(in);
+               } catch (SWTException e) {
+                       // Translate to checked exception!
+                       throw new IOException("SWTException: " + e.getMessage());
+               }
+       }
+       
+       /**
+        * Add a label to the given ToolBar. The label will be aligned to the
+        * vertical center of the ToolBar.
+        * 
+        * @param bar
+        *            A ToolBar.
+        * @param text
+        *            The label text.
+        */
+       public static void addLabel(ToolBar bar, String text) {
+               Composite box = new Composite(bar, SWT.NONE);
+               box.setLayout(new GridLayout());
+               
+               // Create label
+               Label label = new Label(box, SWT.NONE);
+               label.setText(text);
+               
+               // Layout in center of toolbar
+               GridData data = new GridData();
+               data.grabExcessVerticalSpace = true;
+               data.verticalAlignment = SWT.CENTER;
+               label.setLayoutData(data);
+               
+               // Set item size
+               Point sz = box.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+               ToolItem item = new ToolItem(bar, SWT.SEPARATOR);
+               item.setWidth(sz.x);
+               
+               // Set control
+               item.setControl(box);
+       }
+       
+       /**
+        * Add a separator to the given ToolBar. 
+        * 
+        * @param bar
+        *            A ToolBar.
+        */
+       public static void addSeparator(ToolBar bar) {
+               new ToolItem(bar, SWT.SEPARATOR);
+       }
+       
+       /**
+        * Add a Combo box to the given ToolBar. 
+        * 
+        * @param bar
+        *            A ToolBar.
+        * @param width
+        *            The horizontal width to make the ToolBar.
+        * @param style
+        *            The Combo box style.
+        */
+       public static Combo addCombo(ToolBar bar, int width, int style) {
+               ToolItem item = new ToolItem(bar, SWT.SEPARATOR);
+               Combo combo = new Combo(bar, style);
+               item.setWidth(width);
+               item.setControl(combo);
+               return combo;
+       }
+       
+       /**
+        * Center the given shell on the Display.
+        * 
+        * @param shell
+        *            A shell.
+        */
+       public static void center(Shell shell) {
+               Point p = shell.getSize();
+               Rectangle area = shell.getDisplay().getClientArea();
+               
+               int x = area.width / 2 - p.x / 2 + area.x;
+               int y = area.height / 2 - p.y / 2 + area.y;
+               
+               shell.setLocation(x, y);
+       }
+       
+       /**
+        * Center the given shell with respect to the given parent shell.
+        * 
+        * @param parent
+        *            A shell.
+        * @param shell
+        *            The shell to center.
+        */
+       public static void center(Shell parent, Shell shell) {
+               Point p = shell.getSize();
+               Rectangle area = parent.getBounds();
+               
+               int x = area.width / 2 - p.x / 2 + area.x;
+               int y = area.height / 2 - p.y / 2 + area.y;
+               
+               shell.setLocation(x, y);
+       }
+       
+       /**
+        * Returns the SWT image format constant for the given by examining
+        * the file extension of the file.
+        * 
+        * @param file
+        *            A file.
+        * @return The SWT image format constant.
+        */
+       public static int getImageFormat(File file) {
+               String ext = FileUtils.getExtension(file);
+               
+               if (ext != null) {
+                       if (ext.equals("bmp")) {
+                               return SWT.IMAGE_BMP;
+                       } else if (ext.equals("jpg") || ext.equals("jpeg")) {
+                               return SWT.IMAGE_JPEG;
+                       } else if (ext.equals("png")) {
+                               return SWT.IMAGE_PNG;
+                       } else if (ext.equals("gif")) {
+                               return SWT.IMAGE_GIF;
+                       } else if (ext.equals("ico")) {
+                               return SWT.IMAGE_ICO;
+                       }
+               }
+               
+               return -1;
+       }
+       
+       /**
+        * Save the given SWT image to the given file. The format will be determined
+        * from the file extension.
+        * 
+        * @param im
+        *            An image object.
+        * @param file
+        *            The destination file.
+        * @throws IOException
+        *             If there is an error saving the file or the format cannot be
+        *             determined from the filename.
+        */
+       public static void saveImage(Image im, File file) 
+               throws IOException {
+               
+               saveImage(im.getImageData(), file);
+       }
+       
+       /**
+        * Save the given SWT ImageData to the given file. The format will be
+        * determined from the file extension.
+        * 
+        * @param im
+        *            An ImageData object.
+        * @param file
+        *            The destination file.
+        * @throws IOException
+        *             If there is an error saving the file or the format cannot be
+        *             determined from the filename.
+        */
+       public static void saveImage(ImageData im, File file) 
+               throws IOException {
+               
+               // Check if file is a directory
+               if (file.isDirectory()) {
+                       throw new FileNotFoundException(String.format("%s is a directory", file));
+               }
+               
+               // Check if we can write to file
+               if (file.exists()) {
+                       if (!file.canWrite()) {
+                               throw new IOException(String.format("Cannot write to %s", file));
+                       }
+               }
+               
+               // Get image format
+               int format = getImageFormat(file);
+       
+               // Check for unrecognized format
+               if (format < 0) {
+                       String ext = FileUtils.getExtension(file);
+                       throw new IOException(String.format("Unknown format \"%s\"", ext));
+               }
+                       
+               // Create image loader
+               ImageLoader loader = new ImageLoader();
+               loader.data = new ImageData[] { im };
+               
+               try {
+                       // Save image
+                       loader.save(file.getAbsolutePath(), format);
+               
+               } catch (SWTException e) {
+                       // Change unchecked exception to checked one
+                       throw new IOException("SWT Exception: " + e.getMessage());
+               } 
+               
+               // Done
+               return;
+       }
+       
+       /**
+        * Save the given SWT image to the given OutputStream. 
+        * 
+        * @param im
+        *            An image object.
+        * @param out
+        *            The destination output stream.
+        * @param format
+        *            The SWT format constant.
+        * @throws IOException
+        *             If there is an error saving the to the output stream.
+        */
+       public static void saveImage(Image im, OutputStream out, int format) 
+               throws IOException 
+       {
+               saveImage(im.getImageData(), out, format);
+       }
+       
+       /**
+        * Save the given SWT ImageData object to the given OutputStream. 
+        * 
+        * @param im
+        *            An ImageData object.
+        * @param out
+        *            The destination output stream.
+        * @param format
+        *            The SWT format constant.
+        * @throws IOException
+        *             If there is an error saving the to the output stream.
+        */
+       public static void saveImage(ImageData im, OutputStream out, int format) 
+               throws IOException
+       {
+               ImageLoader loader = new ImageLoader();
+               loader.data = new ImageData[] { im };
+               
+               try {
+                       // Save image
+                       loader.save(out, format);
+               
+               } catch (SWTException e) {
+                       // Change unchecked exception to checked one
+                       throw new IOException("SWT Exception: " + e.getMessage());
+               } 
+       }
+               
+       /**
+        * Create a horizontal separator for the given parent.
+        * 
+        * @param parent
+        *            A composite.
+        * @return The created separator control.
+        */
+       public static Control createSeparator(Composite parent) {
+               return new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL);
+       }
+       
+       /**
+        * Turn a SWT control into a file drop target.
+        * 
+        * @param control
+        *        An SWT control (not <code>null</code>).
+        * @param listener
+        *        A file drop listener (not <code>null</code>).
+        */
+       public static void createFileDropTarget(
+                       final Control control, 
+                       final FileDropListener listener) 
+       {
+               // Create target
+               DropTarget target = new DropTarget(
+                               control, DND.DROP_DEFAULT | DND.DROP_MOVE
+               );
+               
+               // Create transfer
+               final FileTransfer transfer = FileTransfer.getInstance();
+               target.setTransfer(new Transfer[] { transfer });
+               
+               // Add listener
+               target.addDropListener(new DropTargetAdapter() {
+                       public void drop(final DropTargetEvent event) {
+                               
+                               
+                               if (transfer.isSupportedType(event.currentDataType)) {
+                                       String[] files = (String[]) event.data;
+                                       
+                                       // Send event
+                                       listener.drop(new FileDropEvent(control, files));
+                               }
+                       }
+               });
+               
+               return;
+       }
+       
+       
+       /**
+        * Compress and RGB object into a ARGB integer.
+        * 
+        * @param rgb
+        *          RGB object.
+        * @return An ARGB integer.
+        */
+       public static int rgb2int(RGB rgb) {
+               return (rgb.red   & 0xff) << 16 | 
+                          (rgb.green & 0xff) << 8  | 
+                          (rgb.blue  & 0xff);
+       }
+       
+       /**
+        * De-compress an ARGB integer into an RGB object.
+        * 
+        * @param v
+        *          an ARGB integer.
+        * @return An RGB object.
+        */
+       public static RGB int2rgb(int v) {
+               return new RGB((v >> 16) & 0xff, (v >> 8) & 0xff, v & 0xff);
+       }
+}
diff --git a/Annotation/src/ie/dcu/swt/event/FileDropEvent.class b/Annotation/src/ie/dcu/swt/event/FileDropEvent.class
new file mode 100644 (file)
index 0000000..cd5d9cf
Binary files /dev/null and b/Annotation/src/ie/dcu/swt/event/FileDropEvent.class differ
diff --git a/Annotation/src/ie/dcu/swt/event/FileDropEvent.java b/Annotation/src/ie/dcu/swt/event/FileDropEvent.java
new file mode 100644 (file)
index 0000000..f8e81b0
--- /dev/null
@@ -0,0 +1,46 @@
+package ie.dcu.swt.event;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * A file drop event.
+ * 
+ * @author Kevin McGuinness
+ */
+public class FileDropEvent extends EventObject {
+       
+       /**
+        * Serialization UID.
+        */
+       private static final long serialVersionUID = -7379037769871853671L;
+       
+       /**
+        * The files.
+        */
+       private final ArrayList<File> files;
+
+       /**
+        * Create a file drop event.
+        * 
+        * @param source
+        *            The source of the file drop.
+        * @param files
+        *            A list of absolute file paths.
+        */
+       public FileDropEvent(Object source, String[] files) {
+               super(source);
+               this.files = new ArrayList<File>(files.length);
+               for (String file : files) {
+                       this.files.add(new File(file));
+               }
+       }
+       
+       /**
+        * Returns an immutable collection of the files for the drop.
+        */
+       public Collection<File> files() {
+               return Collections.unmodifiableCollection(files);
+       }
+
+}
diff --git a/Annotation/src/ie/dcu/swt/event/FileDropListener.class b/Annotation/src/ie/dcu/swt/event/FileDropListener.class
new file mode 100644 (file)
index 0000000..60330e5
Binary files /dev/null and b/Annotation/src/ie/dcu/swt/event/FileDropListener.class differ
diff --git a/Annotation/src/ie/dcu/swt/event/FileDropListener.java b/Annotation/src/ie/dcu/swt/event/FileDropListener.java
new file mode 100644 (file)
index 0000000..7d8be6b
--- /dev/null
@@ -0,0 +1,19 @@
+package ie.dcu.swt.event;
+
+import java.util.*;
+
+/**
+ * A listener for FileDropEvents.
+ * 
+ * @author Kevin McGuinness
+ */
+public interface FileDropListener extends EventListener {
+       
+       /**
+        * Called when a drop occurs.
+        * 
+        * @param evt
+        *            The FileDropEvent object.
+        */
+       public void drop(FileDropEvent evt);
+}
diff --git a/Annotation/src/ie/dcu/swt/event/ImageEvent.class b/Annotation/src/ie/dcu/swt/event/ImageEvent.class
new file mode 100644 (file)
index 0000000..3e14d9f
Binary files /dev/null and b/Annotation/src/ie/dcu/swt/event/ImageEvent.class differ
diff --git a/Annotation/src/ie/dcu/swt/event/ImageEvent.java b/Annotation/src/ie/dcu/swt/event/ImageEvent.java
new file mode 100644 (file)
index 0000000..e223ad6
--- /dev/null
@@ -0,0 +1,56 @@
+package ie.dcu.swt.event;
+
+import ie.dcu.swt.ObservableImage;
+
+import java.util.EventObject;
+
+import org.eclipse.swt.graphics.Rectangle;
+
+/**
+ * An image event.
+ * 
+ * @see ObservableImage
+ * @see ImageListener
+ * @author Kevin McGuinness
+ *
+ */
+public class ImageEvent extends EventObject {
+       private static final long serialVersionUID = 1L;
+
+       /**
+        * The image the fired the event.
+        */
+       public final ObservableImage image;
+       
+       /**
+        * The rectangle that was modified.
+        */
+       public final Rectangle modified;
+
+       /**
+        * Flag to indicate that the image dimensions changed.
+        */
+       private final boolean dimensionsChanged;
+
+       public ImageEvent(
+                       ObservableImage image, 
+                       Rectangle modified,
+                       boolean dimensionsChanged
+       ) {
+               
+               super(image);
+               this.image = image;
+               this.dimensionsChanged = dimensionsChanged;
+               
+               if (modified == null) {
+                       modified = image.getBounds();
+               } 
+
+               this.modified = modified;
+       }
+       
+       public boolean dimensionsChanged() {
+               return dimensionsChanged;
+       }
+
+}
diff --git a/Annotation/src/ie/dcu/swt/event/ImageListener.class b/Annotation/src/ie/dcu/swt/event/ImageListener.class
new file mode 100644 (file)
index 0000000..5b17188
Binary files /dev/null and b/Annotation/src/ie/dcu/swt/event/ImageListener.class differ
diff --git a/Annotation/src/ie/dcu/swt/event/ImageListener.java b/Annotation/src/ie/dcu/swt/event/ImageListener.java
new file mode 100644 (file)
index 0000000..b3522a6
--- /dev/null
@@ -0,0 +1,20 @@
+package ie.dcu.swt.event;
+
+import java.util.*;
+
+/**
+ * Interface for image listeners.
+ * 
+ * @see ie.dcu.swt.ObservableImage
+ * @author Kevin McGuinness
+ */
+public interface ImageListener extends EventListener  {
+       
+       /**
+        * Called when the image is changed.
+        * 
+        * @param e
+        *        The image event object.
+        */
+       public void imageChanged(ImageEvent e);
+}
diff --git a/Annotation/src/ie/dcu/swt/event/ZoomEvent.class b/Annotation/src/ie/dcu/swt/event/ZoomEvent.class
new file mode 100644 (file)
index 0000000..cd9d99d
Binary files /dev/null and b/Annotation/src/ie/dcu/swt/event/ZoomEvent.class differ
diff --git a/Annotation/src/ie/dcu/swt/event/ZoomEvent.java b/Annotation/src/ie/dcu/swt/event/ZoomEvent.java
new file mode 100644 (file)
index 0000000..f94d8a8
--- /dev/null
@@ -0,0 +1,18 @@
+package ie.dcu.swt.event;
+
+import ie.dcu.swt.ImageControl;
+
+import java.util.EventObject;
+
+public class ZoomEvent extends EventObject {
+       private static final long serialVersionUID = 1L;
+
+       public final ImageControl view;
+       public final float scale;
+       
+       public ZoomEvent(ImageControl view) {
+               super(view);
+               this.view = view;
+               this.scale = view.getZoom();
+       }
+}
diff --git a/Annotation/src/ie/dcu/swt/event/ZoomListener.class b/Annotation/src/ie/dcu/swt/event/ZoomListener.class
new file mode 100644 (file)
index 0000000..7df5f99
Binary files /dev/null and b/Annotation/src/ie/dcu/swt/event/ZoomListener.class differ
diff --git a/Annotation/src/ie/dcu/swt/event/ZoomListener.java b/Annotation/src/ie/dcu/swt/event/ZoomListener.java
new file mode 100644 (file)
index 0000000..ac2c726
--- /dev/null
@@ -0,0 +1,7 @@
+package ie.dcu.swt.event;
+
+import java.util.*;
+
+public interface ZoomListener extends EventListener  {
+       public void zoomChanged(ZoomEvent e);
+}
diff --git a/Annotation/src/ie/dcu/swt/layout/BorderData.class b/Annotation/src/ie/dcu/swt/layout/BorderData.class
new file mode 100644 (file)
index 0000000..81bb88a
Binary files /dev/null and b/Annotation/src/ie/dcu/swt/layout/BorderData.class differ
diff --git a/Annotation/src/ie/dcu/swt/layout/BorderData.java b/Annotation/src/ie/dcu/swt/layout/BorderData.java
new file mode 100644 (file)
index 0000000..8c61253
--- /dev/null
@@ -0,0 +1,11 @@
+package ie.dcu.swt.layout;
+
+public enum BorderData {
+       North, South, Center, East, West, Ignore;
+
+       public final int index;
+       
+       private BorderData() {
+               index = ordinal();
+       }
+};
diff --git a/Annotation/src/ie/dcu/swt/layout/BorderLayout.class b/Annotation/src/ie/dcu/swt/layout/BorderLayout.class
new file mode 100644 (file)
index 0000000..2a5c927
Binary files /dev/null and b/Annotation/src/ie/dcu/swt/layout/BorderLayout.class differ
diff --git a/Annotation/src/ie/dcu/swt/layout/BorderLayout.java b/Annotation/src/ie/dcu/swt/layout/BorderLayout.java
new file mode 100644 (file)
index 0000000..d255f82
--- /dev/null
@@ -0,0 +1,187 @@
+package ie.dcu.swt.layout;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.widgets.*;
+
+/**
+ * Port of the AWT BorderLayout.
+ * 
+ * @author Kevin McGuinness
+ */
+public class BorderLayout extends Layout {
+
+       // Typedef indices
+       private static final int N = BorderData.North.index;
+       private static final int S = BorderData.South.index;
+       private static final int C = BorderData.Center.index;
+       private static final int E = BorderData.East.index;
+       private static final int W = BorderData.West.index;
+
+       // Controls in all the regions.
+       private Control[] controls = new Control[5];
+
+       // Cached sizes.
+       private Point[] sizes;
+
+       // Preferred width and height
+       int width, height;
+
+       // Spacing between components
+       int hgap, vgap;
+
+       public BorderLayout() {
+               this(0);
+       }
+
+       public BorderLayout(int space) {
+               hgap = vgap = space;
+       }
+
+       public BorderLayout(int hgap, int vgap) {
+               this.hgap = hgap;
+               this.vgap = vgap;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see
+        * org.eclipse.swt.widgets.Layout#computeSize(org.eclipse.swt.widgets.Composite
+        * , int, int, boolean)
+        */
+       protected Point computeSize(Composite composite, int wHint, int hHint,
+               boolean flushCache) {
+
+               if (sizes == null || flushCache == true) {
+                       refreshSizes(composite.getChildren());
+               }
+
+               int w = wHint;
+               int h = hHint;
+
+               if (w == SWT.DEFAULT)
+                       w = width;
+               if (h == SWT.DEFAULT)
+                       h = height;
+
+               return new Point(w, h);
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see
+        * org.eclipse.swt.widgets.Layout#layout(org.eclipse.swt.widgets.Composite,
+        * boolean)
+        */
+       protected void layout(Composite composite, boolean flushCache) {
+
+               if (flushCache || sizes == null) {
+                       refreshSizes(composite.getChildren());
+               }
+
+               Rectangle r = composite.getClientArea();
+
+               int tg = 0;
+               int bg = 0;
+               int lg = 0;
+               int rg = 0;
+
+               if (controls[N] != null) {
+                       int x = r.x;
+                       int y = r.y;
+                       int w = r.width;
+                       int h = sizes[N].y;
+
+                       controls[N].setBounds(x, y, w, h);
+
+                       tg += hgap;
+               }
+
+               if (controls[S] != null) {
+                       int x = r.x;
+                       int y = r.y + r.height - sizes[S].y;
+                       int w = r.width;
+                       int h = sizes[S].y;
+
+                       controls[S].setBounds(x, y, w, h);
+
+                       bg += hgap;
+               }
+
+               if (controls[W] != null) {
+                       int x = r.x;
+                       int y = r.y + sizes[N].y + tg;
+                       int w = sizes[W].x;
+                       int h = r.height - sizes[N].y - sizes[S].y - (tg + bg);
+
+                       controls[W].setBounds(x, y, w, h);
+
+                       lg += vgap;
+               }
+
+               if (controls[E] != null) {
+                       int x = r.x + r.width - sizes[E].x;
+                       int y = r.y + sizes[N].y + tg;
+                       int w = sizes[E].x;
+                       int h = r.height - sizes[N].y - sizes[S].y - (tg + bg);
+
+                       controls[E].setBounds(x, y, w, h);
+
+                       rg += vgap;
+               }
+
+               if (controls[C] != null) {
+                       int x = r.x + sizes[W].x + lg;
+                       int y = r.y + sizes[N].y + tg;
+                       int w = r.width - sizes[W].x - sizes[E].x - (lg + rg);
+                       int h = r.height - sizes[N].y - sizes[S].y - (tg + bg);
+
+                       controls[C].setBounds(x, y, w, h);
+               }
+
+               return;
+       }
+
+       private void refreshSizes(Control[] children) {
+               for (Control c : children) {
+                       Object o = c.getLayoutData();
+
+                       if (o instanceof BorderData) {
+                               BorderData data = (BorderData) o;
+                               if (data != BorderData.Ignore) {
+                                       controls[data.index] = c;
+                               }
+                       } else {
+                               // Default
+                               controls[C] = c;
+                       }
+               }
+
+               width = height = 0;
+
+               if (sizes == null) {
+                       sizes = new Point[5];
+               }
+
+               for (int i = 0; i < controls.length; i++) {
+                       Control control = controls[i];
+
+                       if (control == null) {
+                               sizes[i] = new Point(0, 0);
+                       } else {
+                               sizes[i] = control.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
+                       }
+               }
+
+               width = Math.max(width, sizes[N].x);
+               width = Math.max(width, sizes[W].x + sizes[C].x + sizes[E].x);
+               width = Math.max(width, sizes[S].x);
+
+               height = Math.max(Math.max(sizes[W].y, sizes[E].y), sizes[C].y)
+                       + sizes[N].y + sizes[S].y;
+
+               return;
+       }
+}
\ No newline at end of file
diff --git a/Annotation/src/ie/dcu/swt/layout/LayoutFactory.class b/Annotation/src/ie/dcu/swt/layout/LayoutFactory.class
new file mode 100644 (file)
index 0000000..55766d3
Binary files /dev/null and b/Annotation/src/ie/dcu/swt/layout/LayoutFactory.class differ
diff --git a/Annotation/src/ie/dcu/swt/layout/LayoutFactory.java b/Annotation/src/ie/dcu/swt/layout/LayoutFactory.java
new file mode 100644 (file)
index 0000000..3e356ef
--- /dev/null
@@ -0,0 +1,36 @@
+package ie.dcu.swt.layout;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.layout.*;
+
+/**
+ * Factory for layouts and layout data objects.
+ * 
+ * @author Kevin McGuinness
+ */
+public class LayoutFactory {
+       
+       public static GridLayout createGridLayout(
+                       int margin, int spacing, int ncols, boolean equal
+       ) {
+               GridLayout layout = createGridLayout(margin, spacing);
+               layout.numColumns = ncols;
+               layout.makeColumnsEqualWidth = equal;
+               return layout;
+       }
+       
+       
+       public static GridLayout createGridLayout(int margin, int spacing) {
+               GridLayout layout = new GridLayout();
+               layout.marginWidth = margin;
+               layout.marginHeight = margin;
+               layout.horizontalSpacing = spacing;
+               layout.verticalSpacing = spacing;
+               return layout;
+       }
+       
+       
+       public static GridData createGridData() {
+               return new GridData(SWT.FILL, SWT.FILL, true, true);
+       }
+}
diff --git a/Annotation/src/ie/dcu/util/ArrayUtils.class b/Annotation/src/ie/dcu/util/ArrayUtils.class
new file mode 100644 (file)
index 0000000..ccf3d9b
Binary files /dev/null and b/Annotation/src/ie/dcu/util/ArrayUtils.class differ
diff --git a/Annotation/src/ie/dcu/util/ArrayUtils.java b/Annotation/src/ie/dcu/util/ArrayUtils.java
new file mode 100644 (file)
index 0000000..d8b24a6
--- /dev/null
@@ -0,0 +1,543 @@
+package ie.dcu.util;
+
+import java.util.*;
+
+/**
+ * Utilities for arrays.
+ * 
+ * @author Kevin McGuinness
+ */
+public class ArrayUtils {
+       
+       /**
+        * Remove the given indices from the given collection.
+        * 
+        * @param c
+        *            The collection.
+        * @param indices
+        *            A list of indices (will be sorted).
+        */
+       public static <T> void remove(Collection<T> c, int[] indices) {
+               Arrays.sort(indices);
+               
+               Iterator<T> iterator = c.iterator();
+               for (int i = 0; iterator.hasNext(); i++) {
+                       iterator.next();
+                       
+                       if (Arrays.binarySearch(indices, i) >= 0) {
+                               iterator.remove();
+                       }
+               }
+       
+               return;
+       }
+       
+       
+       public static void arrayCopy(Object src, int srcPos, Object dst,
+                       int dstPos, int length) 
+       {
+               if (dst.getClass().equals(src.getClass())) {
+
+                       System.arraycopy(src, srcPos, dst, dstPos, length);
+
+               } else {
+                       
+                       // Try for arrays of different primitive types
+
+                       if (src instanceof byte[] && dst instanceof short[]) {
+
+                               // Copy from an array of bytes to array of shorts
+                               arrayCopy((byte[]) src, srcPos, (short[]) dst, dstPos, length);
+
+                       } else if (src instanceof byte[] && dst instanceof int[]) {
+
+                               // Copy from an array of bytes to array of ints
+                               arrayCopy((byte[]) src, srcPos, (int[]) dst, dstPos, length);
+
+                       } else if (src instanceof byte[] && dst instanceof long[]) {
+
+                               // Copy from an array of bytes to array of longs
+                               arrayCopy((byte[]) src, srcPos, (long[]) dst, dstPos, length);
+
+                       } else if (src instanceof byte[] && dst instanceof float[]) {
+
+                               // Copy from an array of bytes to array of floats
+                               arrayCopy((byte[]) src, srcPos, (float[]) dst, dstPos, length);
+
+                       } else if (src instanceof byte[] && dst instanceof double[]) {
+
+                               // Copy from an array of bytes to array of doubles
+                               arrayCopy((byte[]) src, srcPos, (double[]) dst, dstPos, length);
+
+                       } else if (src instanceof short[] && dst instanceof byte[]) {
+
+                               // Copy from an array of shorts to array of bytes
+                               arrayCopy((short[]) src, srcPos, (byte[]) dst, dstPos, length);
+
+                       } else if (src instanceof short[] && dst instanceof int[]) {
+
+                               // Copy from an array of shorts to array of ints
+                               arrayCopy((short[]) src, srcPos, (int[]) dst, dstPos, length);
+
+                       } else if (src instanceof short[] && dst instanceof long[]) {
+
+                               // Copy from an array of shorts to array of longs
+                               arrayCopy((short[]) src, srcPos, (long[]) dst, dstPos, length);
+
+                       } else if (src instanceof short[] && dst instanceof float[]) {
+
+                               // Copy from an array of shorts to array of floats
+                               arrayCopy((short[]) src, srcPos, (float[]) dst, dstPos, length);
+
+                       } else if (src instanceof short[] && dst instanceof double[]) {
+
+                               // Copy from an array of shorts to array of doubles
+                               arrayCopy((short[]) src, srcPos, (double[]) dst, dstPos, length);
+
+                       } else if (src instanceof int[] && dst instanceof byte[]) {
+
+                               // Copy from an array of ints to array of bytes
+                               arrayCopy((int[]) src, srcPos, (byte[]) dst, dstPos, length);
+
+                       } else if (src instanceof int[] && dst instanceof short[]) {
+
+                               // Copy from an array of ints to array of shorts
+                               arrayCopy((int[]) src, srcPos, (short[]) dst, dstPos, length);
+
+                       } else if (src instanceof int[] && dst instanceof long[]) {
+
+                               // Copy from an array of ints to array of longs
+                               arrayCopy((int[]) src, srcPos, (long[]) dst, dstPos, length);
+
+                       } else if (src instanceof int[] && dst instanceof float[]) {
+
+                               // Copy from an array of ints to array of floats
+                               arrayCopy((int[]) src, srcPos, (float[]) dst, dstPos, length);
+
+                       } else if (src instanceof int[] && dst instanceof double[]) {
+
+                               // Copy from an array of ints to array of doubles
+                               arrayCopy((int[]) src, srcPos, (double[]) dst, dstPos, length);
+
+                       } else if (src instanceof long[] && dst instanceof byte[]) {
+
+                               // Copy from an array of longs to array of bytes
+                               arrayCopy((long[]) src, srcPos, (byte[]) dst, dstPos, length);
+
+                       } else if (src instanceof long[] && dst instanceof short[]) {
+
+                               // Copy from an array of longs to array of shorts
+                               arrayCopy((long[]) src, srcPos, (short[]) dst, dstPos, length);
+
+                       } else if (src instanceof long[] && dst instanceof int[]) {
+
+                               // Copy from an array of longs to array of ints
+                               arrayCopy((long[]) src, srcPos, (int[]) dst, dstPos, length);
+
+                       } else if (src instanceof long[] && dst instanceof float[]) {
+
+                               // Copy from an array of longs to array of floats
+                               arrayCopy((long[]) src, srcPos, (float[]) dst, dstPos, length);
+
+                       } else if (src instanceof long[] && dst instanceof double[]) {
+
+                               // Copy from an array of longs to array of doubles
+                               arrayCopy((long[]) src, srcPos, (double[]) dst, dstPos, length);
+
+                       } else if (src instanceof float[] && dst instanceof byte[]) {
+
+                               // Copy from an array of floats to array of bytes
+                               arrayCopy((float[]) src, srcPos, (byte[]) dst, dstPos, length);
+
+                       } else if (src instanceof float[] && dst instanceof short[]) {
+
+                               // Copy from an array of floats to array of shorts
+                               arrayCopy((float[]) src, srcPos, (short[]) dst, dstPos, length);
+
+                       } else if (src instanceof float[] && dst instanceof int[]) {
+
+                               // Copy from an array of floats to array of ints
+                               arrayCopy((float[]) src, srcPos, (int[]) dst, dstPos, length);
+
+                       } else if (src instanceof float[] && dst instanceof long[]) {
+
+                               // Copy from an array of floats to array of longs
+                               arrayCopy((float[]) src, srcPos, (long[]) dst, dstPos, length);
+
+                       } else if (src instanceof float[] && dst instanceof double[]) {
+
+                               // Copy from an array of floats to array of doubles
+                               arrayCopy((float[]) src, srcPos, (double[]) dst, dstPos, length);
+
+                       } else if (src instanceof double[] && dst instanceof byte[]) {
+
+                               // Copy from an array of doubles to array of bytes
+                               arrayCopy((double[]) src, srcPos, (byte[]) dst, dstPos, length);
+
+                       } else if (src instanceof double[] && dst instanceof short[]) {
+
+                               // Copy from an array of doubles to array of shorts
+                               arrayCopy((double[]) src, srcPos, (short[]) dst, dstPos, length);
+
+                       } else if (src instanceof double[] && dst instanceof int[]) {
+
+                               // Copy from an array of doubles to array of ints
+                               arrayCopy((double[]) src, srcPos, (int[]) dst, dstPos, length);
+
+                       } else if (src instanceof double[] && dst instanceof long[]) {
+
+                               // Copy from an array of doubles to array of longs
+                               arrayCopy((double[]) src, srcPos, (long[]) dst, dstPos, length);
+
+                       } else if (src instanceof double[] && dst instanceof float[]) {
+
+                               // Copy from an array of doubles to array of floats
+                               arrayCopy((double[]) src, srcPos, (float[]) dst, dstPos, length);
+
+                       } else {
+
+                               throw new ArrayStoreException();
+                       }
+               }
+       }
+       
+
+       public static void arrayCopy(byte[] src, int srcPos, 
+                       short[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (short) src[srcPos++];
+               }
+       }
+
+       public static void arrayCopy(byte[] src, int srcPos, 
+                       int[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (int) src[srcPos++];
+               }
+       }
+
+       public static void arrayCopy(byte[] src, int srcPos, 
+                       long[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (long) src[srcPos++];
+               }
+       }
+
+       public static void arrayCopy(byte[] src, int srcPos, 
+                       float[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (float) src[srcPos++];
+               }
+       }
+
+       public static void arrayCopy(byte[] src, int srcPos, 
+                       double[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (double) src[srcPos++];
+               }
+       }
+
+       public static void arrayCopy(short[] src, int srcPos, 
+                       byte[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (byte) src[srcPos++];
+               }
+       }
+
+       public static void arrayCopy(short[] src, int srcPos, 
+                       int[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (int) src[srcPos++];
+               }
+       }
+
+       public static void arrayCopy(short[] src, int srcPos, 
+                       long[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (long) src[srcPos++];
+               }
+       }
+
+       public static void arrayCopy(short[] src, int srcPos, 
+                       float[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (float) src[srcPos++];
+               }
+       }
+
+       public static void arrayCopy(short[] src, int srcPos, 
+                       double[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (double) src[srcPos++];
+               }
+       }
+
+       public static void arrayCopy(int[] src, int srcPos, 
+                       byte[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (byte) src[srcPos++];
+               }
+       }
+
+       public static void arrayCopy(int[] src, int srcPos, 
+                       short[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (short) src[srcPos++];
+               }
+       }
+
+       public static void arrayCopy(int[] src, int srcPos, 
+                       long[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (long) src[srcPos++];
+               }
+       }
+
+       public static void arrayCopy(int[] src, int srcPos, 
+                       float[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (float) src[srcPos++];
+               }
+       }
+
+       public static void arrayCopy(int[] src, int srcPos, 
+                       double[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (double) src[srcPos++];
+               }
+       }
+
+       public static void arrayCopy(long[] src, int srcPos, 
+                       byte[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (byte) src[srcPos++];
+               }
+       }
+
+       public static void arrayCopy(long[] src, int srcPos, 
+                       short[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (short) src[srcPos++];
+               }
+       }
+
+       public static void arrayCopy(long[] src, int srcPos, 
+                       int[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (int) src[srcPos++];
+               }
+       }
+
+       public static void arrayCopy(long[] src, int srcPos, 
+                       float[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (float) src[srcPos++];
+               }
+       }
+
+       public static void arrayCopy(long[] src, int srcPos, 
+                       double[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (double) src[srcPos++];
+               }
+       }
+
+       public static void arrayCopy(float[] src, int srcPos, 
+                       byte[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (byte) src[srcPos++];
+               }
+       }
+
+       public static void arrayCopy(float[] src, int srcPos, 
+                       short[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (short) src[srcPos++];
+               }
+       }
+
+       public static void arrayCopy(float[] src, int srcPos, 
+                       int[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (int) src[srcPos++];
+               }
+       }
+
+       public static void arrayCopy(float[] src, int srcPos, 
+                       long[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (long) src[srcPos++];
+               }
+       }
+
+       public static void arrayCopy(float[] src, int srcPos, 
+                       double[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (double) src[srcPos++];
+               }
+       }
+
+       public static void arrayCopy(double[] src, int srcPos, 
+                       byte[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (byte) src[srcPos++];
+               }
+       }
+
+       public static void arrayCopy(double[] src, int srcPos, 
+                       short[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (short) src[srcPos++];
+               }
+       }
+
+       public static void arrayCopy(double[] src, int srcPos, 
+                       int[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (int) src[srcPos++];
+               }
+       }
+
+       public static void arrayCopy(double[] src, int srcPos, 
+                       long[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (long) src[srcPos++];
+               }
+       }
+
+       public static void arrayCopy(double[] src, int srcPos, 
+                       float[] dst, int dstPos, int length) 
+       {
+               checkCopy(src.length, srcPos, dst.length, dstPos, length);
+               
+               for (int i = 0; i < length; i++) {
+                       dst[dstPos++] = (float) src[srcPos++];
+               }
+       }
+       
+       private static void checkCopy(int srcLen, int srcPos, 
+                       int dstLen, int dstPos, int length) 
+       {
+               if (srcPos < 0) {
+                       throw new IllegalArgumentException("srcPos < 0");
+               }
+               
+               if (dstPos < 0) {
+                       throw new IllegalArgumentException("dstPos < 0");
+               }
+               
+               if (length < 0) {
+                       throw new IllegalArgumentException("length < 0");
+               }
+               
+               if (srcPos + length > srcLen) {
+                       throw new IllegalArgumentException("srcPos + length > src.length");
+               }
+               
+               if (dstPos + length > dstLen) {
+                       throw new IllegalArgumentException("dstPos + length > dst.length");
+               }
+       }
+       
+       public static void main(String[] args) {
+               int[] srcArray = {
+                               1, 2, 3, 4, 5
+               };
+               
+               short[] dstArray = new short[srcArray.length];
+               
+               arrayCopy(srcArray, 0, dstArray, 0, srcArray.length);
+               
+               Object srcObj = srcArray;
+               Object dstObj = dstArray;
+               
+               arrayCopy(srcObj, 0, dstObj, 0, srcArray.length);
+       }
+}
diff --git a/Annotation/src/ie/dcu/util/FileUtils.class b/Annotation/src/ie/dcu/util/FileUtils.class
new file mode 100644 (file)
index 0000000..b547efb
Binary files /dev/null and b/Annotation/src/ie/dcu/util/FileUtils.class differ
diff --git a/Annotation/src/ie/dcu/util/FileUtils.java b/Annotation/src/ie/dcu/util/FileUtils.java
new file mode 100644 (file)
index 0000000..0c6e6ac
--- /dev/null
@@ -0,0 +1,383 @@
+package ie.dcu.util;
+
+import java.io.*;
+import java.net.*;
+
+/**
+ * Utility functions for file and filename manipulation.
+ * 
+ * @author Kevin McGuinness
+ */
+public class FileUtils {
+       
+       /**
+        * Size of the copy file buffer.
+        */
+       private static final int BUFFER_SIZE = 8092;
+
+       
+       /**
+        * Returns the file extension of the file. This method returns {@code null} if
+        * the file has no extension. The method also returns {@code null}:
+        * 
+        * <ul>
+        * <li>If the filename contains a period as it's last character</li>
+        * <li>If the filename contains a single period as its first character</li>
+        * </ul>
+        * 
+        * The returned extension is always lowercase.
+        * 
+        * @param file
+        *          The file.
+        * @param includePeriod
+        *          Set to {@code true} to include the period in the returned
+        *          extension.
+        * @return The file extension, or {@code null}
+        */
+       public static final String getExtension(File file, boolean includePeriod) {
+               String filename = file.getName();
+               int idx = filename.lastIndexOf('.'); 
+               
+               // If the period is not the first character or the last
+               if (idx > 0 && idx < filename.length() - 1) {
+                       
+                       if (!includePeriod) {
+                               idx++;
+                       }
+                       
+                       return filename.substring(idx).toLowerCase();
+               }
+               
+               return null;
+       }
+       
+       
+       /**
+        * Returns the file extension of the file. This method returns {@code null} if
+        * the file has no extension. The method also returns {@code null}:
+        * 
+        * <ul>
+        * <li>If the filename contains a period as it's last character</li>
+        * <li>If the filename contains a single period as its first character</li>
+        * </ul>
+        * 
+        * This method does not include the period in the file extension. The returned
+        * extension is always lower-case.
+        * 
+        * @param file
+        *          The file.
+        * @return The file extension, or {@code null}
+        */
+       public static final String getExtension(File file) {
+               return getExtension(file, false);
+       }
+       
+       
+       /**
+        * Remove the file extension from the filename, if it has one.
+        * 
+        * @param filename
+        *          The filename.
+        * @return The filename with the extension removed.
+        */
+       public static final String removeExtension(String filename) {
+               int idx = filename.lastIndexOf('.');
+               if (idx > 0 && idx < filename.length() - 1) {
+                       return filename.substring(0, idx);
+               }
+               return filename;
+       }
+       
+       
+       /**
+        * Replace the file extension with another. If the file has no existing
+        * extension, the new extension will be appended. If the new extension is not
+        * prefixed with a period, one will be added.
+        * 
+        * @param filename
+        *          The filename (not a file path).
+        * @param extension
+        *          The new extension.
+        * @return The filename with the extension replaced.
+        */
+       public static final String replaceExtension(String filename, String extension) {
+               boolean period = extension.startsWith(".");
+               
+               int idx = filename.lastIndexOf('.'); 
+               
+               if (idx > 0 && idx < filename.length() - 1) {
+                       // Strip and append new extension
+                       if (period) {
+                               return filename.substring(0, idx) + extension;
+                       } else {
+                               return filename.substring(0, idx) + "." + extension;
+                       }
+               } 
+               
+               if (period) {
+                       return filename + extension;
+               }
+               
+               return filename + "." + extension;
+       }
+       
+       
+       /**
+        * Returns true if the filename has an extension.
+        * 
+        * @param filename
+        *          The file name (not a file path).
+        * @return {@code true} if it has an extension.
+        */
+       public static boolean hasExtension(String filename) {
+               int idx = filename.lastIndexOf('.'); 
+               return (idx > 0 && idx < filename.length() - 1);
+       }
+       
+       
+       /**
+        * Returns true if the filename has an extension.
+        * 
+        * @param file
+        *          The file.
+        * @return {@code true} if it has an extension.
+        */
+       public static boolean hasExtension(File file) {
+               return hasExtension(file.getName());
+       }
+       
+       
+       /**
+        * Close the stream. Does nothing if it is already closed and ignores any I/O
+        * exception that is thrown.
+        * 
+        * @param c
+        *          The stream, or {@code null}
+        */
+       public static void close(Closeable c) {
+               if (c == null) {
+                       return;
+               }
+               
+               try {
+                       c.close();
+               } catch (IOException e) {
+                       // Intentionally empty
+               }
+       }
+       
+       
+       /**
+        * Copy a source file to a destination. If the destination file exists it is
+        * overwritten. If the destination file is a directory, the file is copied to
+        * that directory.
+        * 
+        * @param src
+        *          The source file.
+        * @param dst
+        *          The target file.
+        * @throws IOException
+        *           If there is a problem copying the file.
+        */
+       public static void copy(File src, File dst) throws IOException {
+               
+               // If directory, copy to file of the same name in that directory
+               if (dst.isDirectory()) {
+                       dst = new File(dst, src.getName());
+               }
+               
+               InputStream in = null;
+               OutputStream out = null;
+               
+               try {
+                       in = new FileInputStream(src);
+                       out = new FileOutputStream(dst);
+                       
+                       // Copy streams
+                       copy(in, out);
+               
+               } finally {     
+                       // Close streams
+                       
+                       if (in != null) {
+                               in.close();
+                       }
+                       
+                       if (out != null) {
+                               out.close();
+                       }
+               }
+               
+               return;
+       }
+
+
+       /**
+        * Copy the data from the input stream to the output stream. The streams are
+        * not closed after the copy.
+        * 
+        * @param in
+        *          The input stream.
+        * @param out
+        *          The output stream.
+        * @throws IOException
+        *           If there is a problem performing the copy.
+        */
+       public static void copy(InputStream in, OutputStream out) throws IOException {
+               byte[] buff = new byte[BUFFER_SIZE];
+               
+               int len;
+               while ((len = in.read(buff)) > 0) {
+                       out.write(buff, 0, len);
+               }
+       }
+       
+       
+       /**
+        * Move the src file to dst. Semantics are the same as copy except that
+        * the source file is deleted after the operation.
+        * 
+        * @param src
+        *          The source file.
+        * @param dst
+        *          The destination.
+        * @return {@code true} if the move is sucessful, {@code false} if the source
+        *         file cannot be removed.
+        * @throws IOException
+        */
+       public static boolean move(File src, File dst) throws IOException {
+               copy(src, dst);
+               return src.delete();
+       }
+       
+       
+       /**
+        * Throws an {@link FileNotFoundException} if the file does not exist.
+        * 
+        * @param file
+        *          The file to check.
+        * @throws FileNotFoundException
+        *           The exception thrown if the file doesn't exist.
+        */
+       public static void checkExists(File file) throws FileNotFoundException {
+               if (!file.exists()) {
+                       throw new FileNotFoundException("File: " + 
+                                       file.getAbsolutePath() + " does not exist");
+               }
+       }
+       
+       
+       /**
+        * Throws an {@link FileNotFoundException} if any of the files do not exist.
+        * 
+        * @param files
+        *          The files to check.
+        * @throws FileNotFoundException
+        *           The exception thrown if any file doesn't exist.
+        */
+       public static void checkExists(File ... files) throws FileNotFoundException {
+               for (File f : files) {
+                       checkExists(f);
+               }
+       }
+       
+       
+       /**
+        * Makes the directory if it doesn't already exist. Throws an exception if
+        * there is an error creating the directory.
+        * 
+        * @param dir
+        *          The directory to create.
+        * @throws IOException
+        *           If there is an error making the directory.
+        */
+       public static void mkdir(File dir) throws IOException {
+               if (dir.isDirectory()) {
+                       return;
+               }
+               
+               if (!dir.mkdir()) {
+                       throw new IOException("Unable to create directory");
+               }
+       }
+       
+       /**
+        * Makes the directory if it doesn't already exist. Throws an exception if
+        * there is an error creating the directory. All intermediate subdirectories
+        * are also created.
+        * 
+        * @param dir
+        *          The directory to create.
+        * @throws IOException
+        *           If there is an error making the directory.
+        */
+       public static void mkdirs(File dir) throws IOException {
+               if (dir.isDirectory()) {
+                       return;
+               }
+               
+               if (!dir.mkdirs()) {
+                       throw new IOException("Unable to create directory");
+               }
+       }
+       
+       
+       /**
+        * Create an absolute url for a file.
+        * 
+        * @param file
+        *          The file.
+        * @return The url
+        */
+       public static URL createAbsoluteURL(File file) {
+               File absolute = file.getAbsoluteFile();
+               try {
+                       return absolute.toURI().toURL();
+               } catch (MalformedURLException e) {
+                       // Shouldn't happen (url cant be malformed, can it?)
+                       return null;
+               }
+       }
+       
+       /**
+        * Join a set of path components using the path separator
+        * 
+        * @param parts
+        *        The path components
+        * @return The joined path
+        */
+       public static String pathJoin(String ... parts) {
+               StringBuilder sb = new StringBuilder();
+               if (parts.length > 0 && parts[0].startsWith(File.separator)) {
+                       // Assume an absolute path
+                       sb.append(File.separator);
+               }
+               
+               for (String part : parts) {
+                       sb.append(normalizePathComponent(part));
+                       if (part != parts[parts.length-1]) {
+                               sb.append(File.separatorChar);
+                       } 
+               }
+               
+               return sb.toString();
+       }
+       
+       /**
+        * Removes leading and trailing path separators from the path component
+        * 
+        * @param component
+        *        A path component
+        * @return A stripped string
+        */
+       private static String normalizePathComponent(String component) {
+               if (component.endsWith(File.separator)) {
+                       component = component.substring(0, File.separator.length());
+               } else if (component.startsWith(File.separator)) {
+                       component = component.substring(File.separator.length());
+               } else {
+                       return component;
+               }
+               return normalizePathComponent(component);
+       }
+}
diff --git a/Annotation/src/ie/dcu/util/OsUtils.class b/Annotation/src/ie/dcu/util/OsUtils.class
new file mode 100644 (file)
index 0000000..a024ef0
Binary files /dev/null and b/Annotation/src/ie/dcu/util/OsUtils.class differ
diff --git a/Annotation/src/ie/dcu/util/OsUtils.java b/Annotation/src/ie/dcu/util/OsUtils.java
new file mode 100644 (file)
index 0000000..45558ea
--- /dev/null
@@ -0,0 +1,61 @@
+package ie.dcu.util;
+
+/**
+ * Utilities for identifying the operating system.
+ * 
+ * @author Kevin McGuinness
+ */
+public class OsUtils {
+       private static final String OS_NAME = "os.name";
+       
+       /**
+        * Returns <code>true</code> if the is Mac OS or Mac OS X.
+        */
+       public static boolean isMacOS() {
+               String os = System.getProperty("os.name");
+               os = os.toLowerCase();
+               return os.startsWith("mac os");
+       }
+
+       /**
+        * Returns <code>true</code> if the OS is Mac OS X.
+        */
+       public static boolean isMacOSX() {
+               String os = System.getProperty(OS_NAME);
+               os = os.toLowerCase();
+               return os.startsWith("mac os x");
+       }
+       
+       /**
+        * Returns <code>true</code> if the OS is an MS Windows variant.
+        */
+       public static boolean isWindows() {
+               String os = System.getProperty(OS_NAME);
+               return os.startsWith("Windows");
+       }
+       
+       /**
+        * Returns <code>true</code> if the OS is a Linux variant.
+        */
+       public static boolean isLinux() {
+               String os = System.getProperty(OS_NAME);
+               return os.startsWith("Linux");
+       }
+       
+       /**
+        * Returns the users home folder.
+        */
+       public static String userHome() {
+               return System.getProperty("user.home");
+       }
+       
+       /**
+        * Returns true if we are on Linux and on a 64 bit Java VM.
+        * 
+        * Note: this is basically guess-work and depends on the VM vendor.
+        * Should work for Sun Java though.
+        */
+       public static boolean isLinux64() {
+               return isLinux() && System.getProperty("os.arch").endsWith("64");
+       }
+}
diff --git a/Annotation/src/ie/dcu/util/PropsUtils.class b/Annotation/src/ie/dcu/util/PropsUtils.class
new file mode 100644 (file)
index 0000000..a97031c
Binary files /dev/null and b/Annotation/src/ie/dcu/util/PropsUtils.class differ
diff --git a/Annotation/src/ie/dcu/util/PropsUtils.java b/Annotation/src/ie/dcu/util/PropsUtils.java
new file mode 100644 (file)
index 0000000..1ded1aa
--- /dev/null
@@ -0,0 +1,71 @@
+package ie.dcu.util;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * Utility functions for <code>.properties</code> files.
+ * 
+ * @author Kevin McGuinness
+ */
+public class PropsUtils {
+       
+       /**
+        * Save the properties object to a file.
+        * 
+        * @param props
+        *          The properties.
+        * @param file
+        *          The file to save it to.
+        * @throws IOException
+        *           If there is an error saving.
+        */
+       public static void save(Properties props, File file) throws IOException {       
+               OutputStream out = null;
+               
+               try {
+                       out = new BufferedOutputStream(new FileOutputStream(file));
+                       props.store(out, "Automatically generated properties file");
+                       
+               } finally {
+                       
+                       if (out != null) out.close();
+               }
+       }
+       
+       
+       /**
+        * Load the properties object from a file.
+        * 
+        * @param file
+        *          The file.
+        * @return A new properties object.
+        * @throws IOException
+        *           If an error occurs loading the properties.
+        */
+       public static Properties load(File file) throws IOException {
+               InputStream in = null;
+               Properties props = null;
+               
+               try {
+                       in = new BufferedInputStream(new FileInputStream(file));
+                       props = new Properties();
+                       props.load(in);
+                       
+               } finally {
+                       
+                       if (in != null) in.close();
+               }
+               
+               return props;
+       }
+       
+       
+       public static File getFile(Properties props, String key) {
+               String val = props.getProperty(key);
+               if (val != null) {
+                       return new File(val);
+               }
+               return null;
+       }
+}
diff --git a/Annotation/src/org/eclipse/core/commands/AbstractHandler.class b/Annotation/src/org/eclipse/core/commands/AbstractHandler.class
new file mode 100644 (file)
index 0000000..fc850b8
Binary files /dev/null and b/Annotation/src/org/eclipse/core/commands/AbstractHandler.class differ
diff --git a/Annotation/src/org/eclipse/core/commands/AbstractHandlerWithState.class b/Annotation/src/org/eclipse/core/commands/AbstractHandlerWithState.class
new file mode 100644 (file)
index 0000000..fd8a738
Binary files /dev/null and b/Annotation/src/org/eclipse/core/commands/AbstractHandlerWithState.class differ
diff --git a/Annotation/src/org/eclipse/core/commands/AbstractParameterValueConverter.class b/Annotation/src/org/eclipse/core/commands/AbstractParameterValueConverter.class
new file mode 100644 (file)
index 0000000..cadd9da
Binary files /dev/null and b/Annotation/src/org/eclipse/core/commands/AbstractParameterValueConverter.class differ
diff --git a/Annotation/src/org/eclipse/core/commands/Category.class b/Annotation/src/org/eclipse/core/commands/Category.class
new file mode 100644 (file)
index 0000000..fd0cd75
Binary files /dev/null and b/Annotation/src/org/eclipse/core/commands/Category.class differ
diff --git a/Annotation/src/org/eclipse/core/commands/CategoryEvent.class b/Annotation/src/org/eclipse/core/commands/CategoryEvent.class
new file mode 100644 (file)
index 0000000..2ff4b62
Binary files /dev/null and b/Annotation/src/org/eclipse/core/commands/CategoryEvent.class differ
diff --git a/Annotation/src/org/eclipse/core/commands/Command$1.class b/Annotation/src/org/eclipse/core/commands/Command$1.class
new file mode 100644 (file)
index 0000000..058b9ef
Binary files /dev/null and b/Annotation/src/org/eclipse/core/commands/Command$1.class differ
diff --git a/Annotation/src/org/eclipse/core/commands/Command$2.class b/Annotation/src/org/eclipse/core/commands/Command$2.class
new file mode 100644 (file)
index 0000000..a6ea8e6
Binary files /dev/null and b/Annotation/src/org/eclipse/core/commands/Command$2.class differ
diff --git a/Annotation/src/org/eclipse/core/commands/Command.class b/Annotation/src/org/eclipse/core/commands/Command.class
new file mode 100644 (file)
index 0000000..07f1d0f
Binary files /dev/null and b/Annotation/src/org/eclipse/core/commands/Command.class differ
diff --git a/Annotation/src/org/eclipse/core/commands/CommandEvent.class b/Annotation/src/org/eclipse/core/commands/CommandEvent.class
new file mode 100644 (file)
index 0000000..211b1eb
Binary files /dev/null and b/Annotation/src/org/eclipse/core/commands/CommandEvent.class differ
diff --git a/Annotation/src/org/eclipse/core/commands/CommandManager$ExecutionListener.class b/Annotation/src/org/eclipse/core/commands/CommandManager$ExecutionListener.class
new file mode 100644 (file)
index 0000000..cfd3c6e
Binary files /dev/null and b/Annotation/src/org/eclipse/core/commands/CommandManager$ExecutionListener.class differ
diff --git a/Annotation/src/org/eclipse/core/commands/CommandManager.class b/Annotation/src/org/eclipse/core/commands/CommandManager.class
new file mode 100644 (file)
index 0000000..5c994e3
Binary files /dev/null and b/Annotation/src/org/eclipse/core/commands/CommandManager.class differ
diff --git a/Annotation/src/org/eclipse/core/commands/CommandManagerEvent.class b/Annotation/src/org/eclipse/core/commands/CommandManagerEvent.class
new file mode 100644 (file)
index 0000000..c147db0
Binary files /dev/null and b/Annotation/src/org/eclipse/core/commands/CommandManagerEvent.class differ
diff --git a/Annotation/src/org/eclipse/core/commands/ExecutionEvent.class b/Annotation/src/org/eclipse/core/commands/ExecutionEvent.class
new file mode 100644 (file)
index 0000000..9588fd5
Binary files /dev/null and b/Annotation/src/org/eclipse/core/commands/ExecutionEvent.class differ
diff --git a/Annotation/src/org/eclipse/core/commands/ExecutionException.class b/Annotation/src/org/eclipse/core/commands/ExecutionException.class
new file mode 100644 (file)
index 0000000..14c3b56
Binary files /dev/null and b/Annotation/src/org/eclipse/core/commands/ExecutionException.class differ
diff --git a/Annotation/src/org/eclipse/core/commands/HandlerEvent.class b/Annotation/src/org/eclipse/core/commands/HandlerEvent.class
new file mode 100644 (file)
index 0000000..7733f7a
Binary files /dev/null and b/Annotation/src/org/eclipse/core/commands/HandlerEvent.class differ
diff --git a/Annotation/src/org/eclipse/core/commands/ICategoryListener.class b/Annotation/src/org/eclipse/core/commands/ICategoryListener.class
new file mode 100644 (file)
index 0000000..2202845
Binary files /dev/null and b/Annotation/src/org/eclipse/core/commands/ICategoryListener.class differ
diff --git a/Annotation/src/org/eclipse/core/commands/ICommandListener.class b/Annotation/src/org/eclipse/core/commands/ICommandListener.class
new file mode 100644 (file)
index 0000000..d4014ab
Binary files /dev/null and b/Annotation/src/org/eclipse/core/commands/ICommandListener.class differ
diff --git a/Annotation/src/org/eclipse/core/commands/ICommandManagerListener.class b/Annotation/src/org/eclipse/core/commands/ICommandManagerListener.class
new file mode 100644 (file)
index 0000000..2f307a5
Binary files /dev/null and b/Annotation/src/org/eclipse/core/commands/ICommandManagerListener.class differ
diff --git a/Annotation/src/org/eclipse/core/commands/IExecutionListener.class b/Annotation/src/org/eclipse/core/commands/IExecutionListener.class
new file mode 100644 (file)
index 0000000..d8b2236
Binary files /dev/null and b/Annotation/src/org/eclipse/core/commands/IExecutionListener.class differ
diff --git a/Annotation/src/org/eclipse/core/commands/IExecutionListenerWithChecks.class b/Annotation/src/org/eclipse/core/commands/IExecutionListenerWithChecks.class
new file mode 100644 (file)
index 0000000..6ca7e50
Binary files /dev/null and b/Annotation/src/org/eclipse/core/commands/IExecutionListenerWithChecks.class differ
diff --git a/Annotation/src/org/eclipse/core/commands/IHandler.class b/Annotation/src/org/eclipse/core/commands/IHandler.class
new file mode 100644 (file)
index 0000000..2cc14d6
Binary files /dev/null and b/Annotation/src/org/eclipse/core/commands/IHandler.class differ
diff --git a/Annotation/src/org/eclipse/core/commands/IHandlerAttributes.class b/Annotation/src/org/eclipse/core/commands/IHandlerAttributes.class
new file mode 100644 (file)
index 0000000..b118cc8
Binary files /dev/null and b/Annotation/src/org/eclipse/core/commands/IHandlerAttributes.class differ
diff --git a/Annotation/src/org/eclipse/core/commands/IHandlerListener.class b/Annotation/src/org/eclipse/core/commands/IHandlerListener.class
new file mode 100644 (file)
index 0000000..6629aab
Binary files /dev/null and b/Annotation/src/org/eclipse/core/commands/IHandlerListener.class differ
diff --git a/Annotation/src/org/eclipse/core/commands/INamedHandleStateIds.class b/Annotation/src/org/eclipse/core/commands/INamedHandleStateIds.class
new file mode 100644 (file)
index 0000000..6edcbe0
Binary files /dev/null and b/Annotation/src/org/eclipse/core/commands/INamedHandleStateIds.class differ
diff --git a/Annotation/src/org/eclipse/core/commands/IObjectWithState.class b/Annotation/src/org/eclipse/core/commands/IObjectWithState.class
new file mode 100644 (file)
index 0000000..a36b10a
Binary files /dev/null and b/Annotation/src/org/eclipse/core/commands/IObjectWithState.class differ
diff --git a/Annotation/src/org/eclipse/core/commands/IParameter.class b/Annotation/src/org/eclipse/core/commands/IParameter.class
new file mode 100644 (file)
index 0000000..6f34587
Binary files /dev/null and b/Annotation/src/org/eclipse/core/commands/IParameter.class differ
diff --git a/Annotation/src/org/eclipse/core/commands/IParameterTypeListener.class b/Annotation/src/org/eclipse/core/commands/IParameterTypeListener.class
new file mode 100644 (file)
index 0000000..c9d42d0
Binary files /dev/null and b/Annotation/src/org/eclipse/core/commands/IParameterTypeListener.class differ
diff --git a/Annotation/src/org/eclipse/core/commands/IParameterValues.class b/Annotation/src/org/eclipse/core/commands/IParameterValues.class
new file mode 100644 (file)
index 0000000..6958a1d
Binary files /dev/null and b/Annotation/src/org/eclipse/core/commands/IParameterValues.class differ
diff --git a/Annotation/src/org/eclipse/core/commands/IStateListener.class b/Annotation/src/org/eclipse/core/commands/IStateListener.class
new file mode 100644 (file)
index 0000000..0222e95
Binary files /dev/null and b/Annotation/src/org/eclipse/core/commands/IStateListener.class differ
diff --git a/Annotation/src/org/eclipse/core/commands/ITypedParameter.class b/Annotation/src/org/eclipse/core/commands/ITypedParameter.class
new file mode 100644 (file)
index 0000000..73c7dbc
Binary files /dev/null and b/Annotation/src/org/eclipse/core/commands/ITypedParameter.class differ
diff --git a/Annotation/src/org/eclipse/core/commands/NamedHandleObjectWithState.class b/Annotation/src/org/eclipse/core/commands/NamedHandleObjectWithState.class
new file mode 100644 (file)
index 0000000..f3d7502
Binary files /dev/null and b/Annotation/src/org/eclipse/core/commands/NamedHandleObjectWithState.class differ
diff --git a/Annotation/src/org/eclipse/core/commands/NotEnabledException.class b/Annotation/src/org/eclipse/core/commands/NotEnabledException.class
new file mode 100644 (file)
index 0000000..13bd30b
Binary files /dev/null and b/Annotation/src/org/eclipse/core/commands/NotEnabledException.class differ
diff --git a/Annotation/src/org/eclipse/core/commands/NotHandledException.class b/Annotation/src/org/eclipse/core/commands/NotHandledException.class
new file mode 100644 (file)
index 0000000..bdcc4ef
Binary files /dev/null and b/Annotation/src/org/eclipse/core/commands/NotHandledException.class differ
diff --git a/Annotation/src/org/eclipse/core/commands/ParameterType.class b/Annotation/src/org/eclipse/core/commands/ParameterType.class
new file mode 100644 (file)
index 0000000..a41fce7
Binary files /dev/null and b/Annotation/src/org/eclipse/core/commands/ParameterType.class differ
diff --git a/Annotation/src/org/eclipse/core/commands/ParameterTypeEvent.class b/Annotation/src/org/eclipse/core/commands/ParameterTypeEvent.class
new file mode 100644 (file)
index 0000000..b2dad9e
Binary files /dev/null and b/Annotation/src/org/eclipse/core/commands/ParameterTypeEvent.class differ
diff --git a/Annotation/src/org/eclipse/core/commands/ParameterValueConversionException.class b/Annotation/src/org/eclipse/core/commands/ParameterValueConversionException.class
new file mode 100644 (file)
index 0000000..6e6f050
Binary files /dev/null and b/Annotation/src/org/eclipse/core/commands/ParameterValueConversionException.class differ
diff --git a/Annotation/src/org/eclipse/core/commands/ParameterValuesException.class b/Annotation/src/org/eclipse/core/commands/ParameterValuesException.class
new file mode 100644 (file)
index 0000000..4a4cdc1
Binary files /dev/null and b/Annotation/src/org/eclipse/core/commands/ParameterValuesException.class differ
diff --git a/Annotation/src/org/eclipse/core/commands/Parameterization.class b/Annotation/src/org/eclipse/core/commands/Parameterization.class
new file mode 100644 (file)
index 0000000..5e4e28d
Binary files /dev/null and b/Annotation/src/org/eclipse/core/commands/Parameterization.class differ
diff --git a/Annotation/src/org/eclipse/core/commands/ParameterizedCommand.class b/Annotation/src/org/eclipse/core/commands/ParameterizedCommand.class
new file mode 100644 (file)
index 0000000..7476ce3
Binary files /dev/null and b/Annotation/src/org/eclipse/core/commands/ParameterizedCommand.class differ
diff --git a/Annotation/src/org/eclipse/core/commands/SerializationException.class b/Annotation/src/org/eclipse/core/commands/SerializationException.class
new file mode 100644 (file)
index 0000000..95f8ebc
Binary files /dev/null and b/Annotation/src/org/eclipse/core/commands/SerializationException.class differ
diff --git a/Annotation/src/org/eclipse/core/commands/State.class b/Annotation/src/org/eclipse/core/commands/State.class
new file mode 100644 (file)
index 0000000..128c208
Binary files /dev/null and b/Annotation/src/org/eclipse/core/commands/State.class differ
diff --git a/Annotation/src/org/eclipse/jface/bindings/Binding.class b/Annotation/src/org/eclipse/jface/bindings/Binding.class
new file mode 100644 (file)
index 0000000..d044cc9
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/bindings/Binding.class differ
diff --git a/Annotation/src/org/eclipse/jface/bindings/BindingManager.class b/Annotation/src/org/eclipse/jface/bindings/BindingManager.class
new file mode 100644 (file)
index 0000000..f7a0a9e
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/bindings/BindingManager.class differ
diff --git a/Annotation/src/org/eclipse/jface/bindings/BindingManagerEvent.class b/Annotation/src/org/eclipse/jface/bindings/BindingManagerEvent.class
new file mode 100644 (file)
index 0000000..3cc6fd8
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/bindings/BindingManagerEvent.class differ
diff --git a/Annotation/src/org/eclipse/jface/bindings/CachedBindingSet.class b/Annotation/src/org/eclipse/jface/bindings/CachedBindingSet.class
new file mode 100644 (file)
index 0000000..22d0f93
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/bindings/CachedBindingSet.class differ
diff --git a/Annotation/src/org/eclipse/jface/bindings/IBindingManagerListener.class b/Annotation/src/org/eclipse/jface/bindings/IBindingManagerListener.class
new file mode 100644 (file)
index 0000000..c0a7264
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/bindings/IBindingManagerListener.class differ
diff --git a/Annotation/src/org/eclipse/jface/bindings/ISchemeListener.class b/Annotation/src/org/eclipse/jface/bindings/ISchemeListener.class
new file mode 100644 (file)
index 0000000..47709d8
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/bindings/ISchemeListener.class differ
diff --git a/Annotation/src/org/eclipse/jface/bindings/Scheme.class b/Annotation/src/org/eclipse/jface/bindings/Scheme.class
new file mode 100644 (file)
index 0000000..aa16d89
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/bindings/Scheme.class differ
diff --git a/Annotation/src/org/eclipse/jface/bindings/SchemeEvent.class b/Annotation/src/org/eclipse/jface/bindings/SchemeEvent.class
new file mode 100644 (file)
index 0000000..74fc849
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/bindings/SchemeEvent.class differ
diff --git a/Annotation/src/org/eclipse/jface/bindings/Trigger.class b/Annotation/src/org/eclipse/jface/bindings/Trigger.class
new file mode 100644 (file)
index 0000000..11a533f
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/bindings/Trigger.class differ
diff --git a/Annotation/src/org/eclipse/jface/bindings/TriggerSequence.class b/Annotation/src/org/eclipse/jface/bindings/TriggerSequence.class
new file mode 100644 (file)
index 0000000..69bb12a
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/bindings/TriggerSequence.class differ
diff --git a/Annotation/src/org/eclipse/jface/bindings/keys/IKeyLookup.class b/Annotation/src/org/eclipse/jface/bindings/keys/IKeyLookup.class
new file mode 100644 (file)
index 0000000..9797341
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/bindings/keys/IKeyLookup.class differ
diff --git a/Annotation/src/org/eclipse/jface/bindings/keys/KeyBinding.class b/Annotation/src/org/eclipse/jface/bindings/keys/KeyBinding.class
new file mode 100644 (file)
index 0000000..d24d7cf
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/bindings/keys/KeyBinding.class differ
diff --git a/Annotation/src/org/eclipse/jface/bindings/keys/KeyLookupFactory.class b/Annotation/src/org/eclipse/jface/bindings/keys/KeyLookupFactory.class
new file mode 100644 (file)
index 0000000..3e3eb4b
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/bindings/keys/KeyLookupFactory.class differ
diff --git a/Annotation/src/org/eclipse/jface/bindings/keys/KeySequence.class b/Annotation/src/org/eclipse/jface/bindings/keys/KeySequence.class
new file mode 100644 (file)
index 0000000..60cd052
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/bindings/keys/KeySequence.class differ
diff --git a/Annotation/src/org/eclipse/jface/bindings/keys/KeySequenceText$1.class b/Annotation/src/org/eclipse/jface/bindings/keys/KeySequenceText$1.class
new file mode 100644 (file)
index 0000000..46add71
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/bindings/keys/KeySequenceText$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/bindings/keys/KeySequenceText$2.class b/Annotation/src/org/eclipse/jface/bindings/keys/KeySequenceText$2.class
new file mode 100644 (file)
index 0000000..cec7e92
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/bindings/keys/KeySequenceText$2.class differ
diff --git a/Annotation/src/org/eclipse/jface/bindings/keys/KeySequenceText$KeyTrapListener.class b/Annotation/src/org/eclipse/jface/bindings/keys/KeySequenceText$KeyTrapListener.class
new file mode 100644 (file)
index 0000000..198ae64
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/bindings/keys/KeySequenceText$KeyTrapListener.class differ
diff --git a/Annotation/src/org/eclipse/jface/bindings/keys/KeySequenceText$TraversalFilter.class b/Annotation/src/org/eclipse/jface/bindings/keys/KeySequenceText$TraversalFilter.class
new file mode 100644 (file)
index 0000000..4143a4e
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/bindings/keys/KeySequenceText$TraversalFilter.class differ
diff --git a/Annotation/src/org/eclipse/jface/bindings/keys/KeySequenceText$TraversalFilterManager.class b/Annotation/src/org/eclipse/jface/bindings/keys/KeySequenceText$TraversalFilterManager.class
new file mode 100644 (file)
index 0000000..7acc7ea
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/bindings/keys/KeySequenceText$TraversalFilterManager.class differ
diff --git a/Annotation/src/org/eclipse/jface/bindings/keys/KeySequenceText$UpdateSequenceListener.class b/Annotation/src/org/eclipse/jface/bindings/keys/KeySequenceText$UpdateSequenceListener.class
new file mode 100644 (file)
index 0000000..c0fad2c
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/bindings/keys/KeySequenceText$UpdateSequenceListener.class differ
diff --git a/Annotation/src/org/eclipse/jface/bindings/keys/KeySequenceText.class b/Annotation/src/org/eclipse/jface/bindings/keys/KeySequenceText.class
new file mode 100644 (file)
index 0000000..79996c0
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/bindings/keys/KeySequenceText.class differ
diff --git a/Annotation/src/org/eclipse/jface/bindings/keys/KeyStroke.class b/Annotation/src/org/eclipse/jface/bindings/keys/KeyStroke.class
new file mode 100644 (file)
index 0000000..fd4228b
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/bindings/keys/KeyStroke.class differ
diff --git a/Annotation/src/org/eclipse/jface/bindings/keys/ParseException.class b/Annotation/src/org/eclipse/jface/bindings/keys/ParseException.class
new file mode 100644 (file)
index 0000000..7c2f40d
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/bindings/keys/ParseException.class differ
diff --git a/Annotation/src/org/eclipse/jface/bindings/keys/SWTKeyLookup.class b/Annotation/src/org/eclipse/jface/bindings/keys/SWTKeyLookup.class
new file mode 100644 (file)
index 0000000..66663bd
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/bindings/keys/SWTKeyLookup.class differ
diff --git a/Annotation/src/org/eclipse/jface/bindings/keys/SWTKeySupport.class b/Annotation/src/org/eclipse/jface/bindings/keys/SWTKeySupport.class
new file mode 100644 (file)
index 0000000..036c546
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/bindings/keys/SWTKeySupport.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/AnimatorFactory.class b/Annotation/src/org/eclipse/jface/dialogs/AnimatorFactory.class
new file mode 100644 (file)
index 0000000..3c90922
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/AnimatorFactory.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/ControlAnimator.class b/Annotation/src/org/eclipse/jface/dialogs/ControlAnimator.class
new file mode 100644 (file)
index 0000000..6ee3984
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/ControlAnimator.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/ControlEnableState$ItemState.class b/Annotation/src/org/eclipse/jface/dialogs/ControlEnableState$ItemState.class
new file mode 100644 (file)
index 0000000..a3e4e3c
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/ControlEnableState$ItemState.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/ControlEnableState.class b/Annotation/src/org/eclipse/jface/dialogs/ControlEnableState.class
new file mode 100644 (file)
index 0000000..8ea2cbf
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/ControlEnableState.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/Dialog$1.class b/Annotation/src/org/eclipse/jface/dialogs/Dialog$1.class
new file mode 100644 (file)
index 0000000..c627ecf
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/Dialog$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/Dialog$2.class b/Annotation/src/org/eclipse/jface/dialogs/Dialog$2.class
new file mode 100644 (file)
index 0000000..9201b84
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/Dialog$2.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/Dialog.class b/Annotation/src/org/eclipse/jface/dialogs/Dialog.class
new file mode 100644 (file)
index 0000000..f033864
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/Dialog.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/DialogMessageArea.class b/Annotation/src/org/eclipse/jface/dialogs/DialogMessageArea.class
new file mode 100644 (file)
index 0000000..ef57ae4
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/DialogMessageArea.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/DialogPage.class b/Annotation/src/org/eclipse/jface/dialogs/DialogPage.class
new file mode 100644 (file)
index 0000000..04332bd
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/DialogPage.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/DialogSettings$XMLWriter.class b/Annotation/src/org/eclipse/jface/dialogs/DialogSettings$XMLWriter.class
new file mode 100644 (file)
index 0000000..7d1aff6
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/DialogSettings$XMLWriter.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/DialogSettings.class b/Annotation/src/org/eclipse/jface/dialogs/DialogSettings.class
new file mode 100644 (file)
index 0000000..396757a
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/DialogSettings.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/DialogTray.class b/Annotation/src/org/eclipse/jface/dialogs/DialogTray.class
new file mode 100644 (file)
index 0000000..ed342aa
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/DialogTray.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/ErrorDialog$1.class b/Annotation/src/org/eclipse/jface/dialogs/ErrorDialog$1.class
new file mode 100644 (file)
index 0000000..cabd784
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/ErrorDialog$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/ErrorDialog.class b/Annotation/src/org/eclipse/jface/dialogs/ErrorDialog.class
new file mode 100644 (file)
index 0000000..46ef1f8
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/ErrorDialog.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/ErrorSupportProvider.class b/Annotation/src/org/eclipse/jface/dialogs/ErrorSupportProvider.class
new file mode 100644 (file)
index 0000000..9dbd478
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/ErrorSupportProvider.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/IDialogBlockedHandler.class b/Annotation/src/org/eclipse/jface/dialogs/IDialogBlockedHandler.class
new file mode 100644 (file)
index 0000000..6fae5f1
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/IDialogBlockedHandler.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/IDialogConstants.class b/Annotation/src/org/eclipse/jface/dialogs/IDialogConstants.class
new file mode 100644 (file)
index 0000000..dd4d8c8
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/IDialogConstants.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/IDialogPage.class b/Annotation/src/org/eclipse/jface/dialogs/IDialogPage.class
new file mode 100644 (file)
index 0000000..e09f48e
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/IDialogPage.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/IDialogSettings.class b/Annotation/src/org/eclipse/jface/dialogs/IDialogSettings.class
new file mode 100644 (file)
index 0000000..a90e811
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/IDialogSettings.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/IInputValidator.class b/Annotation/src/org/eclipse/jface/dialogs/IInputValidator.class
new file mode 100644 (file)
index 0000000..95973a5
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/IInputValidator.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/IMessageProvider.class b/Annotation/src/org/eclipse/jface/dialogs/IMessageProvider.class
new file mode 100644 (file)
index 0000000..58b3966
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/IMessageProvider.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/IPageChangeProvider.class b/Annotation/src/org/eclipse/jface/dialogs/IPageChangeProvider.class
new file mode 100644 (file)
index 0000000..9f9ef6c
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/IPageChangeProvider.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/IPageChangedListener.class b/Annotation/src/org/eclipse/jface/dialogs/IPageChangedListener.class
new file mode 100644 (file)
index 0000000..2a8073d
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/IPageChangedListener.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/IPageChangingListener.class b/Annotation/src/org/eclipse/jface/dialogs/IPageChangingListener.class
new file mode 100644 (file)
index 0000000..be08d35
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/IPageChangingListener.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/IconAndMessageDialog$1.class b/Annotation/src/org/eclipse/jface/dialogs/IconAndMessageDialog$1.class
new file mode 100644 (file)
index 0000000..4741a4d
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/IconAndMessageDialog$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/IconAndMessageDialog$2.class b/Annotation/src/org/eclipse/jface/dialogs/IconAndMessageDialog$2.class
new file mode 100644 (file)
index 0000000..de192a8
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/IconAndMessageDialog$2.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/IconAndMessageDialog.class b/Annotation/src/org/eclipse/jface/dialogs/IconAndMessageDialog.class
new file mode 100644 (file)
index 0000000..a6cd70a
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/IconAndMessageDialog.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/ImageAndMessageArea$1.class b/Annotation/src/org/eclipse/jface/dialogs/ImageAndMessageArea$1.class
new file mode 100644 (file)
index 0000000..255e9ce
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/ImageAndMessageArea$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/ImageAndMessageArea$2.class b/Annotation/src/org/eclipse/jface/dialogs/ImageAndMessageArea$2.class
new file mode 100644 (file)
index 0000000..bf5a6a8
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/ImageAndMessageArea$2.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/ImageAndMessageArea.class b/Annotation/src/org/eclipse/jface/dialogs/ImageAndMessageArea.class
new file mode 100644 (file)
index 0000000..3dea9cc
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/ImageAndMessageArea.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/InputDialog$1.class b/Annotation/src/org/eclipse/jface/dialogs/InputDialog$1.class
new file mode 100644 (file)
index 0000000..ac32009
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/InputDialog$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/InputDialog.class b/Annotation/src/org/eclipse/jface/dialogs/InputDialog.class
new file mode 100644 (file)
index 0000000..5ca4728
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/InputDialog.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/MessageDialog.class b/Annotation/src/org/eclipse/jface/dialogs/MessageDialog.class
new file mode 100644 (file)
index 0000000..c013610
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/MessageDialog.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/MessageDialogWithToggle$1.class b/Annotation/src/org/eclipse/jface/dialogs/MessageDialogWithToggle$1.class
new file mode 100644 (file)
index 0000000..10455aa
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/MessageDialogWithToggle$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/MessageDialogWithToggle.class b/Annotation/src/org/eclipse/jface/dialogs/MessageDialogWithToggle.class
new file mode 100644 (file)
index 0000000..97d5716
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/MessageDialogWithToggle.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/PageChangedEvent.class b/Annotation/src/org/eclipse/jface/dialogs/PageChangedEvent.class
new file mode 100644 (file)
index 0000000..378b2df
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/PageChangedEvent.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/PageChangingEvent.class b/Annotation/src/org/eclipse/jface/dialogs/PageChangingEvent.class
new file mode 100644 (file)
index 0000000..f7f5ffc
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/PageChangingEvent.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/PopupDialog$1.class b/Annotation/src/org/eclipse/jface/dialogs/PopupDialog$1.class
new file mode 100644 (file)
index 0000000..a55d06d
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/PopupDialog$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/PopupDialog$2.class b/Annotation/src/org/eclipse/jface/dialogs/PopupDialog$2.class
new file mode 100644 (file)
index 0000000..ba13b08
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/PopupDialog$2.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/PopupDialog$3.class b/Annotation/src/org/eclipse/jface/dialogs/PopupDialog$3.class
new file mode 100644 (file)
index 0000000..a0e6206
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/PopupDialog$3.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/PopupDialog$4.class b/Annotation/src/org/eclipse/jface/dialogs/PopupDialog$4.class
new file mode 100644 (file)
index 0000000..19ff10c
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/PopupDialog$4.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/PopupDialog$5.class b/Annotation/src/org/eclipse/jface/dialogs/PopupDialog$5.class
new file mode 100644 (file)
index 0000000..98c44fd
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/PopupDialog$5.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/PopupDialog$6.class b/Annotation/src/org/eclipse/jface/dialogs/PopupDialog$6.class
new file mode 100644 (file)
index 0000000..6d18644
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/PopupDialog$6.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/PopupDialog$7.class b/Annotation/src/org/eclipse/jface/dialogs/PopupDialog$7.class
new file mode 100644 (file)
index 0000000..ad77060
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/PopupDialog$7.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/PopupDialog$MoveAction.class b/Annotation/src/org/eclipse/jface/dialogs/PopupDialog$MoveAction.class
new file mode 100644 (file)
index 0000000..4929af2
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/PopupDialog$MoveAction.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/PopupDialog$PersistBoundsAction.class b/Annotation/src/org/eclipse/jface/dialogs/PopupDialog$PersistBoundsAction.class
new file mode 100644 (file)
index 0000000..63102b5
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/PopupDialog$PersistBoundsAction.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/PopupDialog$ResizeAction.class b/Annotation/src/org/eclipse/jface/dialogs/PopupDialog$ResizeAction.class
new file mode 100644 (file)
index 0000000..c3c2e44
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/PopupDialog$ResizeAction.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/PopupDialog.class b/Annotation/src/org/eclipse/jface/dialogs/PopupDialog.class
new file mode 100644 (file)
index 0000000..2415786
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/PopupDialog.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/ProgressIndicator.class b/Annotation/src/org/eclipse/jface/dialogs/ProgressIndicator.class
new file mode 100644 (file)
index 0000000..90bbed1
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/ProgressIndicator.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/ProgressMonitorDialog$1.class b/Annotation/src/org/eclipse/jface/dialogs/ProgressMonitorDialog$1.class
new file mode 100644 (file)
index 0000000..3bb8e8c
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/ProgressMonitorDialog$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/ProgressMonitorDialog$2.class b/Annotation/src/org/eclipse/jface/dialogs/ProgressMonitorDialog$2.class
new file mode 100644 (file)
index 0000000..c947421
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/ProgressMonitorDialog$2.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/ProgressMonitorDialog$3.class b/Annotation/src/org/eclipse/jface/dialogs/ProgressMonitorDialog$3.class
new file mode 100644 (file)
index 0000000..b5e236e
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/ProgressMonitorDialog$3.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/ProgressMonitorDialog$ProgressMonitor.class b/Annotation/src/org/eclipse/jface/dialogs/ProgressMonitorDialog$ProgressMonitor.class
new file mode 100644 (file)
index 0000000..333dc0e
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/ProgressMonitorDialog$ProgressMonitor.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/ProgressMonitorDialog.class b/Annotation/src/org/eclipse/jface/dialogs/ProgressMonitorDialog.class
new file mode 100644 (file)
index 0000000..1054160
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/ProgressMonitorDialog.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/StatusDialog$MessageLine.class b/Annotation/src/org/eclipse/jface/dialogs/StatusDialog$MessageLine.class
new file mode 100644 (file)
index 0000000..50823fb
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/StatusDialog$MessageLine.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/StatusDialog.class b/Annotation/src/org/eclipse/jface/dialogs/StatusDialog.class
new file mode 100644 (file)
index 0000000..6d147eb
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/StatusDialog.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/TitleAreaDialog$1.class b/Annotation/src/org/eclipse/jface/dialogs/TitleAreaDialog$1.class
new file mode 100644 (file)
index 0000000..de0712b
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/TitleAreaDialog$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/TitleAreaDialog.class b/Annotation/src/org/eclipse/jface/dialogs/TitleAreaDialog.class
new file mode 100644 (file)
index 0000000..9cefb2a
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/TitleAreaDialog.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/TrayDialog$1.class b/Annotation/src/org/eclipse/jface/dialogs/TrayDialog$1.class
new file mode 100644 (file)
index 0000000..4dc39db
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/TrayDialog$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/TrayDialog$2.class b/Annotation/src/org/eclipse/jface/dialogs/TrayDialog$2.class
new file mode 100644 (file)
index 0000000..86e3af4
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/TrayDialog$2.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/TrayDialog$3.class b/Annotation/src/org/eclipse/jface/dialogs/TrayDialog$3.class
new file mode 100644 (file)
index 0000000..e36dbda
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/TrayDialog$3.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/TrayDialog$4.class b/Annotation/src/org/eclipse/jface/dialogs/TrayDialog$4.class
new file mode 100644 (file)
index 0000000..3b1a6d1
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/TrayDialog$4.class differ
diff --git a/Annotation/src/org/eclipse/jface/dialogs/TrayDialog.class b/Annotation/src/org/eclipse/jface/dialogs/TrayDialog.class
new file mode 100644 (file)
index 0000000..9e76571
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/dialogs/TrayDialog.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/AutoCompleteField.class b/Annotation/src/org/eclipse/jface/fieldassist/AutoCompleteField.class
new file mode 100644 (file)
index 0000000..9b89167
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/AutoCompleteField.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/ComboContentAdapter.class b/Annotation/src/org/eclipse/jface/fieldassist/ComboContentAdapter.class
new file mode 100644 (file)
index 0000000..53db91c
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/ComboContentAdapter.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$1.class b/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$1.class
new file mode 100644 (file)
index 0000000..b824dcc
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$10.class b/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$10.class
new file mode 100644 (file)
index 0000000..f14a8b4
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$10.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$11.class b/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$11.class
new file mode 100644 (file)
index 0000000..210e0a3
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$11.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$12.class b/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$12.class
new file mode 100644 (file)
index 0000000..aee2769
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$12.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$13.class b/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$13.class
new file mode 100644 (file)
index 0000000..dce0743
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$13.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$14.class b/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$14.class
new file mode 100644 (file)
index 0000000..4703e4c
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$14.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$2.class b/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$2.class
new file mode 100644 (file)
index 0000000..72e052e
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$2.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$3.class b/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$3.class
new file mode 100644 (file)
index 0000000..7e536e2
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$3.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$4.class b/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$4.class
new file mode 100644 (file)
index 0000000..88ee86e
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$4.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$5.class b/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$5.class
new file mode 100644 (file)
index 0000000..62f43d9
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$5.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$6.class b/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$6.class
new file mode 100644 (file)
index 0000000..d022c45
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$6.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$7.class b/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$7.class
new file mode 100644 (file)
index 0000000..55f65b9
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$7.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$8.class b/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$8.class
new file mode 100644 (file)
index 0000000..9d5f41f
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$8.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$9.class b/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$9.class
new file mode 100644 (file)
index 0000000..4354ed6
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$9.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$ContentProposalPopup$InfoPopupDialog.class b/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$ContentProposalPopup$InfoPopupDialog.class
new file mode 100644 (file)
index 0000000..5930358
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$ContentProposalPopup$InfoPopupDialog.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$ContentProposalPopup$PopupCloserListener.class b/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$ContentProposalPopup$PopupCloserListener.class
new file mode 100644 (file)
index 0000000..e7c7fe3
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$ContentProposalPopup$PopupCloserListener.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$ContentProposalPopup$TargetControlListener.class b/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$ContentProposalPopup$TargetControlListener.class
new file mode 100644 (file)
index 0000000..6e1abfb
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$ContentProposalPopup$TargetControlListener.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$ContentProposalPopup.class b/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$ContentProposalPopup.class
new file mode 100644 (file)
index 0000000..639539f
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter$ContentProposalPopup.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter.class b/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter.class
new file mode 100644 (file)
index 0000000..59350df
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/ContentProposalAdapter.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/ControlDecoration$1.class b/Annotation/src/org/eclipse/jface/fieldassist/ControlDecoration$1.class
new file mode 100644 (file)
index 0000000..2c5daff
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/ControlDecoration$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/ControlDecoration$2.class b/Annotation/src/org/eclipse/jface/fieldassist/ControlDecoration$2.class
new file mode 100644 (file)
index 0000000..b4e7489
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/ControlDecoration$2.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/ControlDecoration$3.class b/Annotation/src/org/eclipse/jface/fieldassist/ControlDecoration$3.class
new file mode 100644 (file)
index 0000000..d8494b2
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/ControlDecoration$3.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/ControlDecoration$4.class b/Annotation/src/org/eclipse/jface/fieldassist/ControlDecoration$4.class
new file mode 100644 (file)
index 0000000..7db6078
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/ControlDecoration$4.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/ControlDecoration$5.class b/Annotation/src/org/eclipse/jface/fieldassist/ControlDecoration$5.class
new file mode 100644 (file)
index 0000000..8a7b014
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/ControlDecoration$5.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/ControlDecoration$6.class b/Annotation/src/org/eclipse/jface/fieldassist/ControlDecoration$6.class
new file mode 100644 (file)
index 0000000..b35767f
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/ControlDecoration$6.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/ControlDecoration$7.class b/Annotation/src/org/eclipse/jface/fieldassist/ControlDecoration$7.class
new file mode 100644 (file)
index 0000000..18d711f
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/ControlDecoration$7.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/ControlDecoration$8.class b/Annotation/src/org/eclipse/jface/fieldassist/ControlDecoration$8.class
new file mode 100644 (file)
index 0000000..ad02bf5
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/ControlDecoration$8.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/ControlDecoration$Hover.class b/Annotation/src/org/eclipse/jface/fieldassist/ControlDecoration$Hover.class
new file mode 100644 (file)
index 0000000..218d027
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/ControlDecoration$Hover.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/ControlDecoration.class b/Annotation/src/org/eclipse/jface/fieldassist/ControlDecoration.class
new file mode 100644 (file)
index 0000000..7ae26ed
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/ControlDecoration.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/DecoratedField$1.class b/Annotation/src/org/eclipse/jface/fieldassist/DecoratedField$1.class
new file mode 100644 (file)
index 0000000..45c7c7d
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/DecoratedField$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/DecoratedField$2.class b/Annotation/src/org/eclipse/jface/fieldassist/DecoratedField$2.class
new file mode 100644 (file)
index 0000000..85c252b
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/DecoratedField$2.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/DecoratedField$3.class b/Annotation/src/org/eclipse/jface/fieldassist/DecoratedField$3.class
new file mode 100644 (file)
index 0000000..3443fe2
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/DecoratedField$3.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/DecoratedField$4.class b/Annotation/src/org/eclipse/jface/fieldassist/DecoratedField$4.class
new file mode 100644 (file)
index 0000000..f007039
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/DecoratedField$4.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/DecoratedField$5.class b/Annotation/src/org/eclipse/jface/fieldassist/DecoratedField$5.class
new file mode 100644 (file)
index 0000000..511a721
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/DecoratedField$5.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/DecoratedField$FieldDecorationData.class b/Annotation/src/org/eclipse/jface/fieldassist/DecoratedField$FieldDecorationData.class
new file mode 100644 (file)
index 0000000..48178e6
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/DecoratedField$FieldDecorationData.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/DecoratedField$Hover.class b/Annotation/src/org/eclipse/jface/fieldassist/DecoratedField$Hover.class
new file mode 100644 (file)
index 0000000..a54f58d
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/DecoratedField$Hover.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/DecoratedField.class b/Annotation/src/org/eclipse/jface/fieldassist/DecoratedField.class
new file mode 100644 (file)
index 0000000..d407d50
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/DecoratedField.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/FieldAssistColors$1.class b/Annotation/src/org/eclipse/jface/fieldassist/FieldAssistColors$1.class
new file mode 100644 (file)
index 0000000..0790ff8
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/FieldAssistColors$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/FieldAssistColors.class b/Annotation/src/org/eclipse/jface/fieldassist/FieldAssistColors.class
new file mode 100644 (file)
index 0000000..59eff2d
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/FieldAssistColors.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/FieldDecoration.class b/Annotation/src/org/eclipse/jface/fieldassist/FieldDecoration.class
new file mode 100644 (file)
index 0000000..23e5cf2
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/FieldDecoration.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/FieldDecorationRegistry$Entry.class b/Annotation/src/org/eclipse/jface/fieldassist/FieldDecorationRegistry$Entry.class
new file mode 100644 (file)
index 0000000..0160db4
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/FieldDecorationRegistry$Entry.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/FieldDecorationRegistry.class b/Annotation/src/org/eclipse/jface/fieldassist/FieldDecorationRegistry.class
new file mode 100644 (file)
index 0000000..57f3690
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/FieldDecorationRegistry.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/IContentProposal.class b/Annotation/src/org/eclipse/jface/fieldassist/IContentProposal.class
new file mode 100644 (file)
index 0000000..cba8f79
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/IContentProposal.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/IContentProposalListener.class b/Annotation/src/org/eclipse/jface/fieldassist/IContentProposalListener.class
new file mode 100644 (file)
index 0000000..830168a
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/IContentProposalListener.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/IContentProposalListener2.class b/Annotation/src/org/eclipse/jface/fieldassist/IContentProposalListener2.class
new file mode 100644 (file)
index 0000000..aa5ed94
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/IContentProposalListener2.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/IContentProposalProvider.class b/Annotation/src/org/eclipse/jface/fieldassist/IContentProposalProvider.class
new file mode 100644 (file)
index 0000000..0d8da3d
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/IContentProposalProvider.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/IControlContentAdapter.class b/Annotation/src/org/eclipse/jface/fieldassist/IControlContentAdapter.class
new file mode 100644 (file)
index 0000000..812b7c7
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/IControlContentAdapter.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/IControlCreator.class b/Annotation/src/org/eclipse/jface/fieldassist/IControlCreator.class
new file mode 100644 (file)
index 0000000..7286a2f
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/IControlCreator.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/SimpleContentProposalProvider$1.class b/Annotation/src/org/eclipse/jface/fieldassist/SimpleContentProposalProvider$1.class
new file mode 100644 (file)
index 0000000..409d9d9
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/SimpleContentProposalProvider$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/SimpleContentProposalProvider.class b/Annotation/src/org/eclipse/jface/fieldassist/SimpleContentProposalProvider.class
new file mode 100644 (file)
index 0000000..0d39f34
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/SimpleContentProposalProvider.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/TextContentAdapter.class b/Annotation/src/org/eclipse/jface/fieldassist/TextContentAdapter.class
new file mode 100644 (file)
index 0000000..9b8ed03
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/TextContentAdapter.class differ
diff --git a/Annotation/src/org/eclipse/jface/fieldassist/TextControlCreator.class b/Annotation/src/org/eclipse/jface/fieldassist/TextControlCreator.class
new file mode 100644 (file)
index 0000000..35ffa7d
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/fieldassist/TextControlCreator.class differ
diff --git a/Annotation/src/org/eclipse/jface/internal/InternalPolicy.class b/Annotation/src/org/eclipse/jface/internal/InternalPolicy.class
new file mode 100644 (file)
index 0000000..55053bd
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/internal/InternalPolicy.class differ
diff --git a/Annotation/src/org/eclipse/jface/internal/JFaceActivator.class b/Annotation/src/org/eclipse/jface/internal/JFaceActivator.class
new file mode 100644 (file)
index 0000000..452d5ad
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/internal/JFaceActivator.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/BooleanFieldEditor$1.class b/Annotation/src/org/eclipse/jface/preference/BooleanFieldEditor$1.class
new file mode 100644 (file)
index 0000000..cbc83a6
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/BooleanFieldEditor$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/BooleanFieldEditor$2.class b/Annotation/src/org/eclipse/jface/preference/BooleanFieldEditor$2.class
new file mode 100644 (file)
index 0000000..ca34c7c
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/BooleanFieldEditor$2.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/BooleanFieldEditor.class b/Annotation/src/org/eclipse/jface/preference/BooleanFieldEditor.class
new file mode 100644 (file)
index 0000000..16a7037
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/BooleanFieldEditor.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/BooleanPropertyAction$1.class b/Annotation/src/org/eclipse/jface/preference/BooleanPropertyAction$1.class
new file mode 100644 (file)
index 0000000..f2ff48e
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/BooleanPropertyAction$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/BooleanPropertyAction.class b/Annotation/src/org/eclipse/jface/preference/BooleanPropertyAction.class
new file mode 100644 (file)
index 0000000..987c978
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/BooleanPropertyAction.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/ColorFieldEditor$1.class b/Annotation/src/org/eclipse/jface/preference/ColorFieldEditor$1.class
new file mode 100644 (file)
index 0000000..08cef32
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/ColorFieldEditor$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/ColorFieldEditor.class b/Annotation/src/org/eclipse/jface/preference/ColorFieldEditor.class
new file mode 100644 (file)
index 0000000..04a3b2a
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/ColorFieldEditor.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/ColorSelector$1.class b/Annotation/src/org/eclipse/jface/preference/ColorSelector$1.class
new file mode 100644 (file)
index 0000000..e08d3c1
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/ColorSelector$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/ColorSelector$2.class b/Annotation/src/org/eclipse/jface/preference/ColorSelector$2.class
new file mode 100644 (file)
index 0000000..6ea3401
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/ColorSelector$2.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/ColorSelector$3.class b/Annotation/src/org/eclipse/jface/preference/ColorSelector$3.class
new file mode 100644 (file)
index 0000000..271a8b4
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/ColorSelector$3.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/ColorSelector.class b/Annotation/src/org/eclipse/jface/preference/ColorSelector.class
new file mode 100644 (file)
index 0000000..ca0b370
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/ColorSelector.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/ComboFieldEditor$1.class b/Annotation/src/org/eclipse/jface/preference/ComboFieldEditor$1.class
new file mode 100644 (file)
index 0000000..b9c8218
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/ComboFieldEditor$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/ComboFieldEditor.class b/Annotation/src/org/eclipse/jface/preference/ComboFieldEditor.class
new file mode 100644 (file)
index 0000000..26a7495
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/ComboFieldEditor.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/DirectoryFieldEditor.class b/Annotation/src/org/eclipse/jface/preference/DirectoryFieldEditor.class
new file mode 100644 (file)
index 0000000..62b3239
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/DirectoryFieldEditor.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/FieldEditor$1.class b/Annotation/src/org/eclipse/jface/preference/FieldEditor$1.class
new file mode 100644 (file)
index 0000000..b35285d
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/FieldEditor$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/FieldEditor.class b/Annotation/src/org/eclipse/jface/preference/FieldEditor.class
new file mode 100644 (file)
index 0000000..52691ee
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/FieldEditor.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/FieldEditorPreferencePage.class b/Annotation/src/org/eclipse/jface/preference/FieldEditorPreferencePage.class
new file mode 100644 (file)
index 0000000..0abc87a
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/FieldEditorPreferencePage.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/FileFieldEditor.class b/Annotation/src/org/eclipse/jface/preference/FileFieldEditor.class
new file mode 100644 (file)
index 0000000..f613daf
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/FileFieldEditor.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/FontFieldEditor$1.class b/Annotation/src/org/eclipse/jface/preference/FontFieldEditor$1.class
new file mode 100644 (file)
index 0000000..c292227
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/FontFieldEditor$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/FontFieldEditor$2.class b/Annotation/src/org/eclipse/jface/preference/FontFieldEditor$2.class
new file mode 100644 (file)
index 0000000..9ff0989
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/FontFieldEditor$2.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/FontFieldEditor$3.class b/Annotation/src/org/eclipse/jface/preference/FontFieldEditor$3.class
new file mode 100644 (file)
index 0000000..28519e0
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/FontFieldEditor$3.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/FontFieldEditor$4.class b/Annotation/src/org/eclipse/jface/preference/FontFieldEditor$4.class
new file mode 100644 (file)
index 0000000..f40bdff
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/FontFieldEditor$4.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/FontFieldEditor$DefaultPreviewer.class b/Annotation/src/org/eclipse/jface/preference/FontFieldEditor$DefaultPreviewer.class
new file mode 100644 (file)
index 0000000..44557c1
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/FontFieldEditor$DefaultPreviewer.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/FontFieldEditor.class b/Annotation/src/org/eclipse/jface/preference/FontFieldEditor.class
new file mode 100644 (file)
index 0000000..8e8322c
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/FontFieldEditor.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/IPersistentPreferenceStore.class b/Annotation/src/org/eclipse/jface/preference/IPersistentPreferenceStore.class
new file mode 100644 (file)
index 0000000..e82e311
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/IPersistentPreferenceStore.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/IPreferenceNode.class b/Annotation/src/org/eclipse/jface/preference/IPreferenceNode.class
new file mode 100644 (file)
index 0000000..0813d3a
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/IPreferenceNode.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/IPreferencePage.class b/Annotation/src/org/eclipse/jface/preference/IPreferencePage.class
new file mode 100644 (file)
index 0000000..6b6a51b
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/IPreferencePage.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/IPreferencePageContainer.class b/Annotation/src/org/eclipse/jface/preference/IPreferencePageContainer.class
new file mode 100644 (file)
index 0000000..79dd4e9
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/IPreferencePageContainer.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/IPreferenceStore.class b/Annotation/src/org/eclipse/jface/preference/IPreferenceStore.class
new file mode 100644 (file)
index 0000000..47184c4
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/IPreferenceStore.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/IntegerFieldEditor.class b/Annotation/src/org/eclipse/jface/preference/IntegerFieldEditor.class
new file mode 100644 (file)
index 0000000..21ffd68
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/IntegerFieldEditor.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/JFacePreferences.class b/Annotation/src/org/eclipse/jface/preference/JFacePreferences.class
new file mode 100644 (file)
index 0000000..c1cca33
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/JFacePreferences.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/ListEditor$1.class b/Annotation/src/org/eclipse/jface/preference/ListEditor$1.class
new file mode 100644 (file)
index 0000000..dd50193
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/ListEditor$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/ListEditor$2.class b/Annotation/src/org/eclipse/jface/preference/ListEditor$2.class
new file mode 100644 (file)
index 0000000..dc8c62a
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/ListEditor$2.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/ListEditor$3.class b/Annotation/src/org/eclipse/jface/preference/ListEditor$3.class
new file mode 100644 (file)
index 0000000..1239c09
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/ListEditor$3.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/ListEditor.class b/Annotation/src/org/eclipse/jface/preference/ListEditor.class
new file mode 100644 (file)
index 0000000..99104e8
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/ListEditor.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/PathEditor.class b/Annotation/src/org/eclipse/jface/preference/PathEditor.class
new file mode 100644 (file)
index 0000000..a1db579
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/PathEditor.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/PreferenceContentProvider.class b/Annotation/src/org/eclipse/jface/preference/PreferenceContentProvider.class
new file mode 100644 (file)
index 0000000..1bab969
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/PreferenceContentProvider.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/PreferenceConverter.class b/Annotation/src/org/eclipse/jface/preference/PreferenceConverter.class
new file mode 100644 (file)
index 0000000..2ad40c4
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/PreferenceConverter.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$1.class b/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$1.class
new file mode 100644 (file)
index 0000000..53ad119
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$10.class b/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$10.class
new file mode 100644 (file)
index 0000000..d7a250c
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$10.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$11.class b/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$11.class
new file mode 100644 (file)
index 0000000..420b691
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$11.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$12.class b/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$12.class
new file mode 100644 (file)
index 0000000..318846e
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$12.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$13.class b/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$13.class
new file mode 100644 (file)
index 0000000..b53ffc9
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$13.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$14.class b/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$14.class
new file mode 100644 (file)
index 0000000..4ca47d6
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$14.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$15.class b/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$15.class
new file mode 100644 (file)
index 0000000..150f5b2
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$15.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$2.class b/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$2.class
new file mode 100644 (file)
index 0000000..8e84a00
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$2.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$3.class b/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$3.class
new file mode 100644 (file)
index 0000000..e4e5a91
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$3.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$4.class b/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$4.class
new file mode 100644 (file)
index 0000000..623cd85
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$4.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$5.class b/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$5.class
new file mode 100644 (file)
index 0000000..4cc8abb
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$5.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$6.class b/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$6.class
new file mode 100644 (file)
index 0000000..87c7dcf
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$6.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$7.class b/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$7.class
new file mode 100644 (file)
index 0000000..6d8854f
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$7.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$8.class b/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$8.class
new file mode 100644 (file)
index 0000000..e7ec5fd
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$8.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$9.class b/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$9.class
new file mode 100644 (file)
index 0000000..af6bf4b
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$9.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$PageLayout.class b/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$PageLayout.class
new file mode 100644 (file)
index 0000000..7e7394d
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/PreferenceDialog$PageLayout.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/PreferenceDialog.class b/Annotation/src/org/eclipse/jface/preference/PreferenceDialog.class
new file mode 100644 (file)
index 0000000..cccb55d
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/PreferenceDialog.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/PreferenceLabelProvider.class b/Annotation/src/org/eclipse/jface/preference/PreferenceLabelProvider.class
new file mode 100644 (file)
index 0000000..834cda0
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/PreferenceLabelProvider.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/PreferenceManager.class b/Annotation/src/org/eclipse/jface/preference/PreferenceManager.class
new file mode 100644 (file)
index 0000000..a6a29b0
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/PreferenceManager.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/PreferenceNode.class b/Annotation/src/org/eclipse/jface/preference/PreferenceNode.class
new file mode 100644 (file)
index 0000000..9330d00
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/PreferenceNode.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/PreferencePage$1.class b/Annotation/src/org/eclipse/jface/preference/PreferencePage$1.class
new file mode 100644 (file)
index 0000000..2b856aa
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/PreferencePage$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/PreferencePage$2.class b/Annotation/src/org/eclipse/jface/preference/PreferencePage$2.class
new file mode 100644 (file)
index 0000000..7d4cb7a
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/PreferencePage$2.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/PreferencePage$3.class b/Annotation/src/org/eclipse/jface/preference/PreferencePage$3.class
new file mode 100644 (file)
index 0000000..fbc511f
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/PreferencePage$3.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/PreferencePage$4.class b/Annotation/src/org/eclipse/jface/preference/PreferencePage$4.class
new file mode 100644 (file)
index 0000000..2bf4bb4
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/PreferencePage$4.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/PreferencePage.class b/Annotation/src/org/eclipse/jface/preference/PreferencePage.class
new file mode 100644 (file)
index 0000000..9b04c37
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/PreferencePage.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/PreferenceStore$1.class b/Annotation/src/org/eclipse/jface/preference/PreferenceStore$1.class
new file mode 100644 (file)
index 0000000..2a1eb41
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/PreferenceStore$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/PreferenceStore.class b/Annotation/src/org/eclipse/jface/preference/PreferenceStore.class
new file mode 100644 (file)
index 0000000..5a99b8f
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/PreferenceStore.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/RadioGroupFieldEditor$1.class b/Annotation/src/org/eclipse/jface/preference/RadioGroupFieldEditor$1.class
new file mode 100644 (file)
index 0000000..bcce391
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/RadioGroupFieldEditor$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/RadioGroupFieldEditor$2.class b/Annotation/src/org/eclipse/jface/preference/RadioGroupFieldEditor$2.class
new file mode 100644 (file)
index 0000000..3ed0f08
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/RadioGroupFieldEditor$2.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/RadioGroupFieldEditor.class b/Annotation/src/org/eclipse/jface/preference/RadioGroupFieldEditor.class
new file mode 100644 (file)
index 0000000..9d84f73
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/RadioGroupFieldEditor.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/ScaleFieldEditor$1.class b/Annotation/src/org/eclipse/jface/preference/ScaleFieldEditor$1.class
new file mode 100644 (file)
index 0000000..04e2373
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/ScaleFieldEditor$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/ScaleFieldEditor$2.class b/Annotation/src/org/eclipse/jface/preference/ScaleFieldEditor$2.class
new file mode 100644 (file)
index 0000000..4b3412e
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/ScaleFieldEditor$2.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/ScaleFieldEditor.class b/Annotation/src/org/eclipse/jface/preference/ScaleFieldEditor.class
new file mode 100644 (file)
index 0000000..d3f936c
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/ScaleFieldEditor.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/StringButtonFieldEditor$1.class b/Annotation/src/org/eclipse/jface/preference/StringButtonFieldEditor$1.class
new file mode 100644 (file)
index 0000000..37ac228
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/StringButtonFieldEditor$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/StringButtonFieldEditor$2.class b/Annotation/src/org/eclipse/jface/preference/StringButtonFieldEditor$2.class
new file mode 100644 (file)
index 0000000..fda2d7b
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/StringButtonFieldEditor$2.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/StringButtonFieldEditor.class b/Annotation/src/org/eclipse/jface/preference/StringButtonFieldEditor.class
new file mode 100644 (file)
index 0000000..47328bb
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/StringButtonFieldEditor.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/StringFieldEditor$1.class b/Annotation/src/org/eclipse/jface/preference/StringFieldEditor$1.class
new file mode 100644 (file)
index 0000000..779eb17
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/StringFieldEditor$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/StringFieldEditor$2.class b/Annotation/src/org/eclipse/jface/preference/StringFieldEditor$2.class
new file mode 100644 (file)
index 0000000..3877f15
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/StringFieldEditor$2.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/StringFieldEditor$3.class b/Annotation/src/org/eclipse/jface/preference/StringFieldEditor$3.class
new file mode 100644 (file)
index 0000000..7465f58
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/StringFieldEditor$3.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/StringFieldEditor$4.class b/Annotation/src/org/eclipse/jface/preference/StringFieldEditor$4.class
new file mode 100644 (file)
index 0000000..384af70
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/StringFieldEditor$4.class differ
diff --git a/Annotation/src/org/eclipse/jface/preference/StringFieldEditor.class b/Annotation/src/org/eclipse/jface/preference/StringFieldEditor.class
new file mode 100644 (file)
index 0000000..bcf7808
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/preference/StringFieldEditor.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/AbstractListViewer$1.class b/Annotation/src/org/eclipse/jface/viewers/AbstractListViewer$1.class
new file mode 100644 (file)
index 0000000..8cf84e3
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/AbstractListViewer$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/AbstractListViewer.class b/Annotation/src/org/eclipse/jface/viewers/AbstractListViewer.class
new file mode 100644 (file)
index 0000000..08f293c
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/AbstractListViewer.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/AbstractTableViewer$1.class b/Annotation/src/org/eclipse/jface/viewers/AbstractTableViewer$1.class
new file mode 100644 (file)
index 0000000..962d7b9
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/AbstractTableViewer$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/AbstractTableViewer$2.class b/Annotation/src/org/eclipse/jface/viewers/AbstractTableViewer$2.class
new file mode 100644 (file)
index 0000000..11dd2ee
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/AbstractTableViewer$2.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/AbstractTableViewer$3.class b/Annotation/src/org/eclipse/jface/viewers/AbstractTableViewer$3.class
new file mode 100644 (file)
index 0000000..a2d890e
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/AbstractTableViewer$3.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/AbstractTableViewer$VirtualManager.class b/Annotation/src/org/eclipse/jface/viewers/AbstractTableViewer$VirtualManager.class
new file mode 100644 (file)
index 0000000..b76d33d
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/AbstractTableViewer$VirtualManager.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/AbstractTableViewer.class b/Annotation/src/org/eclipse/jface/viewers/AbstractTableViewer.class
new file mode 100644 (file)
index 0000000..120409f
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/AbstractTableViewer.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/AbstractTreeViewer$1.class b/Annotation/src/org/eclipse/jface/viewers/AbstractTreeViewer$1.class
new file mode 100644 (file)
index 0000000..b4dd9eb
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/AbstractTreeViewer$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/AbstractTreeViewer$2.class b/Annotation/src/org/eclipse/jface/viewers/AbstractTreeViewer$2.class
new file mode 100644 (file)
index 0000000..0e8957d
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/AbstractTreeViewer$2.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/AbstractTreeViewer$3.class b/Annotation/src/org/eclipse/jface/viewers/AbstractTreeViewer$3.class
new file mode 100644 (file)
index 0000000..f20e204
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/AbstractTreeViewer$3.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/AbstractTreeViewer$4.class b/Annotation/src/org/eclipse/jface/viewers/AbstractTreeViewer$4.class
new file mode 100644 (file)
index 0000000..30d1313
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/AbstractTreeViewer$4.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/AbstractTreeViewer$5.class b/Annotation/src/org/eclipse/jface/viewers/AbstractTreeViewer$5.class
new file mode 100644 (file)
index 0000000..a2e6566
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/AbstractTreeViewer$5.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/AbstractTreeViewer$6.class b/Annotation/src/org/eclipse/jface/viewers/AbstractTreeViewer$6.class
new file mode 100644 (file)
index 0000000..ba98ac2
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/AbstractTreeViewer$6.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/AbstractTreeViewer$7.class b/Annotation/src/org/eclipse/jface/viewers/AbstractTreeViewer$7.class
new file mode 100644 (file)
index 0000000..74e31e9
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/AbstractTreeViewer$7.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/AbstractTreeViewer$8.class b/Annotation/src/org/eclipse/jface/viewers/AbstractTreeViewer$8.class
new file mode 100644 (file)
index 0000000..dd77079
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/AbstractTreeViewer$8.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/AbstractTreeViewer$UpdateItemSafeRunnable.class b/Annotation/src/org/eclipse/jface/viewers/AbstractTreeViewer$UpdateItemSafeRunnable.class
new file mode 100644 (file)
index 0000000..c7400c2
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/AbstractTreeViewer$UpdateItemSafeRunnable.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/AbstractTreeViewer.class b/Annotation/src/org/eclipse/jface/viewers/AbstractTreeViewer.class
new file mode 100644 (file)
index 0000000..decfa1c
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/AbstractTreeViewer.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/AcceptAllFilter.class b/Annotation/src/org/eclipse/jface/viewers/AcceptAllFilter.class
new file mode 100644 (file)
index 0000000..b29e36a
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/AcceptAllFilter.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ArrayContentProvider.class b/Annotation/src/org/eclipse/jface/viewers/ArrayContentProvider.class
new file mode 100644 (file)
index 0000000..d5f9e27
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ArrayContentProvider.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/BaseLabelProvider$1.class b/Annotation/src/org/eclipse/jface/viewers/BaseLabelProvider$1.class
new file mode 100644 (file)
index 0000000..6964d8f
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/BaseLabelProvider$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/BaseLabelProvider.class b/Annotation/src/org/eclipse/jface/viewers/BaseLabelProvider.class
new file mode 100644 (file)
index 0000000..032547e
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/BaseLabelProvider.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/CellEditor$1.class b/Annotation/src/org/eclipse/jface/viewers/CellEditor$1.class
new file mode 100644 (file)
index 0000000..1bb8d46
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/CellEditor$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/CellEditor$2.class b/Annotation/src/org/eclipse/jface/viewers/CellEditor$2.class
new file mode 100644 (file)
index 0000000..072d9ef
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/CellEditor$2.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/CellEditor$3.class b/Annotation/src/org/eclipse/jface/viewers/CellEditor$3.class
new file mode 100644 (file)
index 0000000..07f34ac
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/CellEditor$3.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/CellEditor$4.class b/Annotation/src/org/eclipse/jface/viewers/CellEditor$4.class
new file mode 100644 (file)
index 0000000..78078d6
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/CellEditor$4.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/CellEditor$LayoutData.class b/Annotation/src/org/eclipse/jface/viewers/CellEditor$LayoutData.class
new file mode 100644 (file)
index 0000000..82b1af3
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/CellEditor$LayoutData.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/CellEditor.class b/Annotation/src/org/eclipse/jface/viewers/CellEditor.class
new file mode 100644 (file)
index 0000000..aa4900f
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/CellEditor.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/CellLabelProvider.class b/Annotation/src/org/eclipse/jface/viewers/CellLabelProvider.class
new file mode 100644 (file)
index 0000000..95fb75d
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/CellLabelProvider.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/CellNavigationStrategy.class b/Annotation/src/org/eclipse/jface/viewers/CellNavigationStrategy.class
new file mode 100644 (file)
index 0000000..2e6c39e
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/CellNavigationStrategy.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/CheckStateChangedEvent.class b/Annotation/src/org/eclipse/jface/viewers/CheckStateChangedEvent.class
new file mode 100644 (file)
index 0000000..5603a73
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/CheckStateChangedEvent.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/CheckboxCellEditor.class b/Annotation/src/org/eclipse/jface/viewers/CheckboxCellEditor.class
new file mode 100644 (file)
index 0000000..2551188
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/CheckboxCellEditor.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/CheckboxTableViewer$1.class b/Annotation/src/org/eclipse/jface/viewers/CheckboxTableViewer$1.class
new file mode 100644 (file)
index 0000000..fea876b
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/CheckboxTableViewer$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/CheckboxTableViewer.class b/Annotation/src/org/eclipse/jface/viewers/CheckboxTableViewer.class
new file mode 100644 (file)
index 0000000..8891919
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/CheckboxTableViewer.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/CheckboxTreeViewer$1.class b/Annotation/src/org/eclipse/jface/viewers/CheckboxTreeViewer$1.class
new file mode 100644 (file)
index 0000000..8dce48f
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/CheckboxTreeViewer$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/CheckboxTreeViewer.class b/Annotation/src/org/eclipse/jface/viewers/CheckboxTreeViewer.class
new file mode 100644 (file)
index 0000000..c152f49
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/CheckboxTreeViewer.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ColorCellEditor$ColorCellLayout.class b/Annotation/src/org/eclipse/jface/viewers/ColorCellEditor$ColorCellLayout.class
new file mode 100644 (file)
index 0000000..760fa1f
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ColorCellEditor$ColorCellLayout.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ColorCellEditor.class b/Annotation/src/org/eclipse/jface/viewers/ColorCellEditor.class
new file mode 100644 (file)
index 0000000..3bd23a4
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ColorCellEditor.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ColumnLabelProvider.class b/Annotation/src/org/eclipse/jface/viewers/ColumnLabelProvider.class
new file mode 100644 (file)
index 0000000..99fd61e
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ColumnLabelProvider.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ColumnLayoutData.class b/Annotation/src/org/eclipse/jface/viewers/ColumnLayoutData.class
new file mode 100644 (file)
index 0000000..827afd1
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ColumnLayoutData.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ColumnPixelData.class b/Annotation/src/org/eclipse/jface/viewers/ColumnPixelData.class
new file mode 100644 (file)
index 0000000..6b16156
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ColumnPixelData.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ColumnViewer$1.class b/Annotation/src/org/eclipse/jface/viewers/ColumnViewer$1.class
new file mode 100644 (file)
index 0000000..8d4b3e6
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ColumnViewer$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ColumnViewer$2.class b/Annotation/src/org/eclipse/jface/viewers/ColumnViewer$2.class
new file mode 100644 (file)
index 0000000..02bef7f
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ColumnViewer$2.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ColumnViewer$3.class b/Annotation/src/org/eclipse/jface/viewers/ColumnViewer$3.class
new file mode 100644 (file)
index 0000000..039e877
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ColumnViewer$3.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ColumnViewer.class b/Annotation/src/org/eclipse/jface/viewers/ColumnViewer.class
new file mode 100644 (file)
index 0000000..0107596
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ColumnViewer.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ColumnViewerEditor$1.class b/Annotation/src/org/eclipse/jface/viewers/ColumnViewerEditor$1.class
new file mode 100644 (file)
index 0000000..2cfda3a
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ColumnViewerEditor$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ColumnViewerEditor$2.class b/Annotation/src/org/eclipse/jface/viewers/ColumnViewerEditor$2.class
new file mode 100644 (file)
index 0000000..ae866c7
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ColumnViewerEditor$2.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ColumnViewerEditor$3.class b/Annotation/src/org/eclipse/jface/viewers/ColumnViewerEditor$3.class
new file mode 100644 (file)
index 0000000..c760f0b
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ColumnViewerEditor$3.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ColumnViewerEditor$4.class b/Annotation/src/org/eclipse/jface/viewers/ColumnViewerEditor$4.class
new file mode 100644 (file)
index 0000000..70b3819
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ColumnViewerEditor$4.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ColumnViewerEditor.class b/Annotation/src/org/eclipse/jface/viewers/ColumnViewerEditor.class
new file mode 100644 (file)
index 0000000..a29c9e3
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ColumnViewerEditor.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ColumnViewerEditorActivationEvent.class b/Annotation/src/org/eclipse/jface/viewers/ColumnViewerEditorActivationEvent.class
new file mode 100644 (file)
index 0000000..82a8d7f
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ColumnViewerEditorActivationEvent.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ColumnViewerEditorActivationListener.class b/Annotation/src/org/eclipse/jface/viewers/ColumnViewerEditorActivationListener.class
new file mode 100644 (file)
index 0000000..c0ad51e
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ColumnViewerEditorActivationListener.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ColumnViewerEditorActivationStrategy$1.class b/Annotation/src/org/eclipse/jface/viewers/ColumnViewerEditorActivationStrategy$1.class
new file mode 100644 (file)
index 0000000..9144e3e
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ColumnViewerEditorActivationStrategy$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ColumnViewerEditorActivationStrategy.class b/Annotation/src/org/eclipse/jface/viewers/ColumnViewerEditorActivationStrategy.class
new file mode 100644 (file)
index 0000000..92a59df
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ColumnViewerEditorActivationStrategy.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ColumnViewerEditorDeactivationEvent.class b/Annotation/src/org/eclipse/jface/viewers/ColumnViewerEditorDeactivationEvent.class
new file mode 100644 (file)
index 0000000..2aea3ea
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ColumnViewerEditorDeactivationEvent.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ColumnViewerToolTipSupport.class b/Annotation/src/org/eclipse/jface/viewers/ColumnViewerToolTipSupport.class
new file mode 100644 (file)
index 0000000..18321c6
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ColumnViewerToolTipSupport.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ColumnWeightData.class b/Annotation/src/org/eclipse/jface/viewers/ColumnWeightData.class
new file mode 100644 (file)
index 0000000..3eda5fa
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ColumnWeightData.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ComboBoxCellEditor$1.class b/Annotation/src/org/eclipse/jface/viewers/ComboBoxCellEditor$1.class
new file mode 100644 (file)
index 0000000..3baa994
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ComboBoxCellEditor$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ComboBoxCellEditor$2.class b/Annotation/src/org/eclipse/jface/viewers/ComboBoxCellEditor$2.class
new file mode 100644 (file)
index 0000000..f4c1497
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ComboBoxCellEditor$2.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ComboBoxCellEditor$3.class b/Annotation/src/org/eclipse/jface/viewers/ComboBoxCellEditor$3.class
new file mode 100644 (file)
index 0000000..6806a72
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ComboBoxCellEditor$3.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ComboBoxCellEditor$4.class b/Annotation/src/org/eclipse/jface/viewers/ComboBoxCellEditor$4.class
new file mode 100644 (file)
index 0000000..9e747ea
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ComboBoxCellEditor$4.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ComboBoxCellEditor.class b/Annotation/src/org/eclipse/jface/viewers/ComboBoxCellEditor.class
new file mode 100644 (file)
index 0000000..c959445
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ComboBoxCellEditor.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ComboViewer.class b/Annotation/src/org/eclipse/jface/viewers/ComboViewer.class
new file mode 100644 (file)
index 0000000..5109aa8
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ComboViewer.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ContentViewer$1.class b/Annotation/src/org/eclipse/jface/viewers/ContentViewer$1.class
new file mode 100644 (file)
index 0000000..ae57115
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ContentViewer$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ContentViewer$2.class b/Annotation/src/org/eclipse/jface/viewers/ContentViewer$2.class
new file mode 100644 (file)
index 0000000..0d526fa
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ContentViewer$2.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ContentViewer.class b/Annotation/src/org/eclipse/jface/viewers/ContentViewer.class
new file mode 100644 (file)
index 0000000..d4f4179
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ContentViewer.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/CustomHashtable$EmptyEnumerator.class b/Annotation/src/org/eclipse/jface/viewers/CustomHashtable$EmptyEnumerator.class
new file mode 100644 (file)
index 0000000..f820ba1
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/CustomHashtable$EmptyEnumerator.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/CustomHashtable$HashEnumerator.class b/Annotation/src/org/eclipse/jface/viewers/CustomHashtable$HashEnumerator.class
new file mode 100644 (file)
index 0000000..230b9bb
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/CustomHashtable$HashEnumerator.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/CustomHashtable$HashMapEntry.class b/Annotation/src/org/eclipse/jface/viewers/CustomHashtable$HashMapEntry.class
new file mode 100644 (file)
index 0000000..34bee2b
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/CustomHashtable$HashMapEntry.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/CustomHashtable.class b/Annotation/src/org/eclipse/jface/viewers/CustomHashtable.class
new file mode 100644 (file)
index 0000000..ef67732
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/CustomHashtable.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/DecoratingLabelProvider.class b/Annotation/src/org/eclipse/jface/viewers/DecoratingLabelProvider.class
new file mode 100644 (file)
index 0000000..31f1eda
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/DecoratingLabelProvider.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/DecorationContext.class b/Annotation/src/org/eclipse/jface/viewers/DecorationContext.class
new file mode 100644 (file)
index 0000000..9b05054
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/DecorationContext.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/DecorationOverlayIcon.class b/Annotation/src/org/eclipse/jface/viewers/DecorationOverlayIcon.class
new file mode 100644 (file)
index 0000000..1041b1b
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/DecorationOverlayIcon.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/DialogCellEditor$1.class b/Annotation/src/org/eclipse/jface/viewers/DialogCellEditor$1.class
new file mode 100644 (file)
index 0000000..9edc676
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/DialogCellEditor$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/DialogCellEditor$2.class b/Annotation/src/org/eclipse/jface/viewers/DialogCellEditor$2.class
new file mode 100644 (file)
index 0000000..2deff8f
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/DialogCellEditor$2.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/DialogCellEditor$3.class b/Annotation/src/org/eclipse/jface/viewers/DialogCellEditor$3.class
new file mode 100644 (file)
index 0000000..54b3d6a
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/DialogCellEditor$3.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/DialogCellEditor$DialogCellLayout.class b/Annotation/src/org/eclipse/jface/viewers/DialogCellEditor$DialogCellLayout.class
new file mode 100644 (file)
index 0000000..fa07760
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/DialogCellEditor$DialogCellLayout.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/DialogCellEditor.class b/Annotation/src/org/eclipse/jface/viewers/DialogCellEditor.class
new file mode 100644 (file)
index 0000000..9cf7294
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/DialogCellEditor.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/DoubleClickEvent.class b/Annotation/src/org/eclipse/jface/viewers/DoubleClickEvent.class
new file mode 100644 (file)
index 0000000..2004d3e
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/DoubleClickEvent.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/EditingSupport.class b/Annotation/src/org/eclipse/jface/viewers/EditingSupport.class
new file mode 100644 (file)
index 0000000..877743c
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/EditingSupport.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/FocusCellHighlighter.class b/Annotation/src/org/eclipse/jface/viewers/FocusCellHighlighter.class
new file mode 100644 (file)
index 0000000..21febb1
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/FocusCellHighlighter.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/FocusCellOwnerDrawHighlighter$1.class b/Annotation/src/org/eclipse/jface/viewers/FocusCellOwnerDrawHighlighter$1.class
new file mode 100644 (file)
index 0000000..aa6a8d5
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/FocusCellOwnerDrawHighlighter$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/FocusCellOwnerDrawHighlighter.class b/Annotation/src/org/eclipse/jface/viewers/FocusCellOwnerDrawHighlighter.class
new file mode 100644 (file)
index 0000000..440c081
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/FocusCellOwnerDrawHighlighter.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/IBaseLabelProvider.class b/Annotation/src/org/eclipse/jface/viewers/IBaseLabelProvider.class
new file mode 100644 (file)
index 0000000..0e4c8fc
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/IBaseLabelProvider.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/IBasicPropertyConstants.class b/Annotation/src/org/eclipse/jface/viewers/IBasicPropertyConstants.class
new file mode 100644 (file)
index 0000000..ee723c3
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/IBasicPropertyConstants.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ICellEditorListener.class b/Annotation/src/org/eclipse/jface/viewers/ICellEditorListener.class
new file mode 100644 (file)
index 0000000..25b8fc5
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ICellEditorListener.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ICellEditorValidator.class b/Annotation/src/org/eclipse/jface/viewers/ICellEditorValidator.class
new file mode 100644 (file)
index 0000000..374ea80
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ICellEditorValidator.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ICellModifier.class b/Annotation/src/org/eclipse/jface/viewers/ICellModifier.class
new file mode 100644 (file)
index 0000000..0dc7de9
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ICellModifier.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ICheckStateListener.class b/Annotation/src/org/eclipse/jface/viewers/ICheckStateListener.class
new file mode 100644 (file)
index 0000000..4c92f50
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ICheckStateListener.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ICheckable.class b/Annotation/src/org/eclipse/jface/viewers/ICheckable.class
new file mode 100644 (file)
index 0000000..422cd20
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ICheckable.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/IColorDecorator.class b/Annotation/src/org/eclipse/jface/viewers/IColorDecorator.class
new file mode 100644 (file)
index 0000000..b85b087
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/IColorDecorator.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/IColorProvider.class b/Annotation/src/org/eclipse/jface/viewers/IColorProvider.class
new file mode 100644 (file)
index 0000000..6014cc6
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/IColorProvider.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/IContentProvider.class b/Annotation/src/org/eclipse/jface/viewers/IContentProvider.class
new file mode 100644 (file)
index 0000000..885bad4
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/IContentProvider.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/IDecoration.class b/Annotation/src/org/eclipse/jface/viewers/IDecoration.class
new file mode 100644 (file)
index 0000000..39afe8e
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/IDecoration.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/IDecorationContext.class b/Annotation/src/org/eclipse/jface/viewers/IDecorationContext.class
new file mode 100644 (file)
index 0000000..6291bce
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/IDecorationContext.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/IDelayedLabelDecorator.class b/Annotation/src/org/eclipse/jface/viewers/IDelayedLabelDecorator.class
new file mode 100644 (file)
index 0000000..8a2e0d0
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/IDelayedLabelDecorator.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/IDoubleClickListener.class b/Annotation/src/org/eclipse/jface/viewers/IDoubleClickListener.class
new file mode 100644 (file)
index 0000000..d52178f
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/IDoubleClickListener.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/IElementComparer.class b/Annotation/src/org/eclipse/jface/viewers/IElementComparer.class
new file mode 100644 (file)
index 0000000..b469bce
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/IElementComparer.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/IFilter.class b/Annotation/src/org/eclipse/jface/viewers/IFilter.class
new file mode 100644 (file)
index 0000000..75ef315
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/IFilter.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/IFontDecorator.class b/Annotation/src/org/eclipse/jface/viewers/IFontDecorator.class
new file mode 100644 (file)
index 0000000..c676029
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/IFontDecorator.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/IFontProvider.class b/Annotation/src/org/eclipse/jface/viewers/IFontProvider.class
new file mode 100644 (file)
index 0000000..1fee662
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/IFontProvider.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/IInputProvider.class b/Annotation/src/org/eclipse/jface/viewers/IInputProvider.class
new file mode 100644 (file)
index 0000000..c660d5b
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/IInputProvider.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/IInputSelectionProvider.class b/Annotation/src/org/eclipse/jface/viewers/IInputSelectionProvider.class
new file mode 100644 (file)
index 0000000..9ce7929
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/IInputSelectionProvider.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ILabelDecorator.class b/Annotation/src/org/eclipse/jface/viewers/ILabelDecorator.class
new file mode 100644 (file)
index 0000000..2bd92b1
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ILabelDecorator.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ILabelProvider.class b/Annotation/src/org/eclipse/jface/viewers/ILabelProvider.class
new file mode 100644 (file)
index 0000000..ebe905f
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ILabelProvider.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ILabelProviderListener.class b/Annotation/src/org/eclipse/jface/viewers/ILabelProviderListener.class
new file mode 100644 (file)
index 0000000..eca9cd7
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ILabelProviderListener.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ILazyContentProvider.class b/Annotation/src/org/eclipse/jface/viewers/ILazyContentProvider.class
new file mode 100644 (file)
index 0000000..ae0a63e
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ILazyContentProvider.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ILazyTreeContentProvider.class b/Annotation/src/org/eclipse/jface/viewers/ILazyTreeContentProvider.class
new file mode 100644 (file)
index 0000000..0f4053e
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ILazyTreeContentProvider.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ILazyTreePathContentProvider.class b/Annotation/src/org/eclipse/jface/viewers/ILazyTreePathContentProvider.class
new file mode 100644 (file)
index 0000000..4eb5eee
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ILazyTreePathContentProvider.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ILightweightLabelDecorator.class b/Annotation/src/org/eclipse/jface/viewers/ILightweightLabelDecorator.class
new file mode 100644 (file)
index 0000000..307a0f1
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ILightweightLabelDecorator.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/IOpenListener.class b/Annotation/src/org/eclipse/jface/viewers/IOpenListener.class
new file mode 100644 (file)
index 0000000..25bbdd1
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/IOpenListener.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/IPostSelectionProvider.class b/Annotation/src/org/eclipse/jface/viewers/IPostSelectionProvider.class
new file mode 100644 (file)
index 0000000..9f55853
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/IPostSelectionProvider.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ISelection.class b/Annotation/src/org/eclipse/jface/viewers/ISelection.class
new file mode 100644 (file)
index 0000000..c245e43
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ISelection.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ISelectionChangedListener.class b/Annotation/src/org/eclipse/jface/viewers/ISelectionChangedListener.class
new file mode 100644 (file)
index 0000000..4b43eb3
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ISelectionChangedListener.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ISelectionProvider.class b/Annotation/src/org/eclipse/jface/viewers/ISelectionProvider.class
new file mode 100644 (file)
index 0000000..4736d63
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ISelectionProvider.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/IStructuredContentProvider.class b/Annotation/src/org/eclipse/jface/viewers/IStructuredContentProvider.class
new file mode 100644 (file)
index 0000000..5a72211
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/IStructuredContentProvider.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/IStructuredSelection.class b/Annotation/src/org/eclipse/jface/viewers/IStructuredSelection.class
new file mode 100644 (file)
index 0000000..03dbd1a
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/IStructuredSelection.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ITableColorProvider.class b/Annotation/src/org/eclipse/jface/viewers/ITableColorProvider.class
new file mode 100644 (file)
index 0000000..808f14a
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ITableColorProvider.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ITableFontProvider.class b/Annotation/src/org/eclipse/jface/viewers/ITableFontProvider.class
new file mode 100644 (file)
index 0000000..c767520
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ITableFontProvider.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ITableLabelProvider.class b/Annotation/src/org/eclipse/jface/viewers/ITableLabelProvider.class
new file mode 100644 (file)
index 0000000..1638ace
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ITableLabelProvider.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ITreeContentProvider.class b/Annotation/src/org/eclipse/jface/viewers/ITreeContentProvider.class
new file mode 100644 (file)
index 0000000..a992263
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ITreeContentProvider.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ITreePathContentProvider.class b/Annotation/src/org/eclipse/jface/viewers/ITreePathContentProvider.class
new file mode 100644 (file)
index 0000000..ddf1471
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ITreePathContentProvider.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ITreePathLabelProvider.class b/Annotation/src/org/eclipse/jface/viewers/ITreePathLabelProvider.class
new file mode 100644 (file)
index 0000000..333443f
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ITreePathLabelProvider.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ITreeSelection.class b/Annotation/src/org/eclipse/jface/viewers/ITreeSelection.class
new file mode 100644 (file)
index 0000000..8166df9
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ITreeSelection.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ITreeViewerListener.class b/Annotation/src/org/eclipse/jface/viewers/ITreeViewerListener.class
new file mode 100644 (file)
index 0000000..ba0a84b
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ITreeViewerListener.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/IViewerLabelProvider.class b/Annotation/src/org/eclipse/jface/viewers/IViewerLabelProvider.class
new file mode 100644 (file)
index 0000000..56c7167
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/IViewerLabelProvider.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/LabelDecorator.class b/Annotation/src/org/eclipse/jface/viewers/LabelDecorator.class
new file mode 100644 (file)
index 0000000..1233fb2
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/LabelDecorator.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/LabelProvider.class b/Annotation/src/org/eclipse/jface/viewers/LabelProvider.class
new file mode 100644 (file)
index 0000000..8fda3fc
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/LabelProvider.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/LabelProviderChangedEvent.class b/Annotation/src/org/eclipse/jface/viewers/LabelProviderChangedEvent.class
new file mode 100644 (file)
index 0000000..0d96c88
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/LabelProviderChangedEvent.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ListViewer.class b/Annotation/src/org/eclipse/jface/viewers/ListViewer.class
new file mode 100644 (file)
index 0000000..62ec486
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ListViewer.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/NamedHandleObjectLabelProvider.class b/Annotation/src/org/eclipse/jface/viewers/NamedHandleObjectLabelProvider.class
new file mode 100644 (file)
index 0000000..ffb6b41
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/NamedHandleObjectLabelProvider.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/OpenEvent.class b/Annotation/src/org/eclipse/jface/viewers/OpenEvent.class
new file mode 100644 (file)
index 0000000..7c6b7bd
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/OpenEvent.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/OwnerDrawLabelProvider$1.class b/Annotation/src/org/eclipse/jface/viewers/OwnerDrawLabelProvider$1.class
new file mode 100644 (file)
index 0000000..39569fd
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/OwnerDrawLabelProvider$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/OwnerDrawLabelProvider$2.class b/Annotation/src/org/eclipse/jface/viewers/OwnerDrawLabelProvider$2.class
new file mode 100644 (file)
index 0000000..88d3ee2
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/OwnerDrawLabelProvider$2.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/OwnerDrawLabelProvider$3.class b/Annotation/src/org/eclipse/jface/viewers/OwnerDrawLabelProvider$3.class
new file mode 100644 (file)
index 0000000..21f765b
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/OwnerDrawLabelProvider$3.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/OwnerDrawLabelProvider.class b/Annotation/src/org/eclipse/jface/viewers/OwnerDrawLabelProvider.class
new file mode 100644 (file)
index 0000000..aea2b46
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/OwnerDrawLabelProvider.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/SWTFocusCellManager$1.class b/Annotation/src/org/eclipse/jface/viewers/SWTFocusCellManager$1.class
new file mode 100644 (file)
index 0000000..599be83
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/SWTFocusCellManager$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/SWTFocusCellManager$2.class b/Annotation/src/org/eclipse/jface/viewers/SWTFocusCellManager$2.class
new file mode 100644 (file)
index 0000000..9fb75e0
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/SWTFocusCellManager$2.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/SWTFocusCellManager$3.class b/Annotation/src/org/eclipse/jface/viewers/SWTFocusCellManager$3.class
new file mode 100644 (file)
index 0000000..03606f8
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/SWTFocusCellManager$3.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/SWTFocusCellManager.class b/Annotation/src/org/eclipse/jface/viewers/SWTFocusCellManager.class
new file mode 100644 (file)
index 0000000..57e6b57
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/SWTFocusCellManager.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/SelectionChangedEvent.class b/Annotation/src/org/eclipse/jface/viewers/SelectionChangedEvent.class
new file mode 100644 (file)
index 0000000..6199b71
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/SelectionChangedEvent.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/StructuredSelection.class b/Annotation/src/org/eclipse/jface/viewers/StructuredSelection.class
new file mode 100644 (file)
index 0000000..27e23bb
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/StructuredSelection.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/StructuredViewer$1.class b/Annotation/src/org/eclipse/jface/viewers/StructuredViewer$1.class
new file mode 100644 (file)
index 0000000..20bec0e
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/StructuredViewer$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/StructuredViewer$2.class b/Annotation/src/org/eclipse/jface/viewers/StructuredViewer$2.class
new file mode 100644 (file)
index 0000000..690ee96
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/StructuredViewer$2.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/StructuredViewer$3.class b/Annotation/src/org/eclipse/jface/viewers/StructuredViewer$3.class
new file mode 100644 (file)
index 0000000..ea8ab53
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/StructuredViewer$3.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/StructuredViewer$4.class b/Annotation/src/org/eclipse/jface/viewers/StructuredViewer$4.class
new file mode 100644 (file)
index 0000000..b56116b
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/StructuredViewer$4.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/StructuredViewer$5.class b/Annotation/src/org/eclipse/jface/viewers/StructuredViewer$5.class
new file mode 100644 (file)
index 0000000..9447435
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/StructuredViewer$5.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/StructuredViewer$6.class b/Annotation/src/org/eclipse/jface/viewers/StructuredViewer$6.class
new file mode 100644 (file)
index 0000000..29904a6
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/StructuredViewer$6.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/StructuredViewer$7.class b/Annotation/src/org/eclipse/jface/viewers/StructuredViewer$7.class
new file mode 100644 (file)
index 0000000..abf8c67
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/StructuredViewer$7.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/StructuredViewer$8.class b/Annotation/src/org/eclipse/jface/viewers/StructuredViewer$8.class
new file mode 100644 (file)
index 0000000..661984c
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/StructuredViewer$8.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/StructuredViewer$9.class b/Annotation/src/org/eclipse/jface/viewers/StructuredViewer$9.class
new file mode 100644 (file)
index 0000000..b4d8314
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/StructuredViewer$9.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/StructuredViewer$ColorAndFontCollector.class b/Annotation/src/org/eclipse/jface/viewers/StructuredViewer$ColorAndFontCollector.class
new file mode 100644 (file)
index 0000000..a4bddce
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/StructuredViewer$ColorAndFontCollector.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/StructuredViewer$ColorAndFontCollectorWithProviders.class b/Annotation/src/org/eclipse/jface/viewers/StructuredViewer$ColorAndFontCollectorWithProviders.class
new file mode 100644 (file)
index 0000000..2e2cdbc
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/StructuredViewer$ColorAndFontCollectorWithProviders.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/StructuredViewer$UpdateItemSafeRunnable.class b/Annotation/src/org/eclipse/jface/viewers/StructuredViewer$UpdateItemSafeRunnable.class
new file mode 100644 (file)
index 0000000..9d7005c
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/StructuredViewer$UpdateItemSafeRunnable.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/StructuredViewer.class b/Annotation/src/org/eclipse/jface/viewers/StructuredViewer.class
new file mode 100644 (file)
index 0000000..cbbb2a1
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/StructuredViewer.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/TableColumnViewerLabelProvider.class b/Annotation/src/org/eclipse/jface/viewers/TableColumnViewerLabelProvider.class
new file mode 100644 (file)
index 0000000..e264c23
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/TableColumnViewerLabelProvider.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/TableLayout.class b/Annotation/src/org/eclipse/jface/viewers/TableLayout.class
new file mode 100644 (file)
index 0000000..6d95dd1
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/TableLayout.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/TableTreeViewer$1.class b/Annotation/src/org/eclipse/jface/viewers/TableTreeViewer$1.class
new file mode 100644 (file)
index 0000000..0a6a9b6
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/TableTreeViewer$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/TableTreeViewer$2.class b/Annotation/src/org/eclipse/jface/viewers/TableTreeViewer$2.class
new file mode 100644 (file)
index 0000000..8dce620
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/TableTreeViewer$2.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/TableTreeViewer$3.class b/Annotation/src/org/eclipse/jface/viewers/TableTreeViewer$3.class
new file mode 100644 (file)
index 0000000..d7c5f8f
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/TableTreeViewer$3.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/TableTreeViewer$4.class b/Annotation/src/org/eclipse/jface/viewers/TableTreeViewer$4.class
new file mode 100644 (file)
index 0000000..b0e276b
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/TableTreeViewer$4.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/TableTreeViewer$TableTreeEditorImpl.class b/Annotation/src/org/eclipse/jface/viewers/TableTreeViewer$TableTreeEditorImpl.class
new file mode 100644 (file)
index 0000000..56967a4
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/TableTreeViewer$TableTreeEditorImpl.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/TableTreeViewer.class b/Annotation/src/org/eclipse/jface/viewers/TableTreeViewer.class
new file mode 100644 (file)
index 0000000..9399f88
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/TableTreeViewer.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/TableViewer$1.class b/Annotation/src/org/eclipse/jface/viewers/TableViewer$1.class
new file mode 100644 (file)
index 0000000..8bd1d1b
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/TableViewer$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/TableViewer.class b/Annotation/src/org/eclipse/jface/viewers/TableViewer.class
new file mode 100644 (file)
index 0000000..a083fcd
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/TableViewer.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/TableViewerColumn.class b/Annotation/src/org/eclipse/jface/viewers/TableViewerColumn.class
new file mode 100644 (file)
index 0000000..ab9176e
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/TableViewerColumn.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/TableViewerEditor.class b/Annotation/src/org/eclipse/jface/viewers/TableViewerEditor.class
new file mode 100644 (file)
index 0000000..f192412
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/TableViewerEditor.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/TableViewerFocusCellManager.class b/Annotation/src/org/eclipse/jface/viewers/TableViewerFocusCellManager.class
new file mode 100644 (file)
index 0000000..42786fe
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/TableViewerFocusCellManager.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/TableViewerRow.class b/Annotation/src/org/eclipse/jface/viewers/TableViewerRow.class
new file mode 100644 (file)
index 0000000..92fa6f2
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/TableViewerRow.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/TextCellEditor$1.class b/Annotation/src/org/eclipse/jface/viewers/TextCellEditor$1.class
new file mode 100644 (file)
index 0000000..efe4f7e
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/TextCellEditor$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/TextCellEditor$2.class b/Annotation/src/org/eclipse/jface/viewers/TextCellEditor$2.class
new file mode 100644 (file)
index 0000000..6aa9b2a
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/TextCellEditor$2.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/TextCellEditor$3.class b/Annotation/src/org/eclipse/jface/viewers/TextCellEditor$3.class
new file mode 100644 (file)
index 0000000..9b098e2
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/TextCellEditor$3.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/TextCellEditor$4.class b/Annotation/src/org/eclipse/jface/viewers/TextCellEditor$4.class
new file mode 100644 (file)
index 0000000..29aede9
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/TextCellEditor$4.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/TextCellEditor$5.class b/Annotation/src/org/eclipse/jface/viewers/TextCellEditor$5.class
new file mode 100644 (file)
index 0000000..5c97f1e
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/TextCellEditor$5.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/TextCellEditor$6.class b/Annotation/src/org/eclipse/jface/viewers/TextCellEditor$6.class
new file mode 100644 (file)
index 0000000..fa803d9
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/TextCellEditor$6.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/TextCellEditor.class b/Annotation/src/org/eclipse/jface/viewers/TextCellEditor.class
new file mode 100644 (file)
index 0000000..9782e3f
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/TextCellEditor.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/TreeColumnViewerLabelProvider$1.class b/Annotation/src/org/eclipse/jface/viewers/TreeColumnViewerLabelProvider$1.class
new file mode 100644 (file)
index 0000000..d5a7ccf
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/TreeColumnViewerLabelProvider$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/TreeColumnViewerLabelProvider.class b/Annotation/src/org/eclipse/jface/viewers/TreeColumnViewerLabelProvider.class
new file mode 100644 (file)
index 0000000..5de7cba
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/TreeColumnViewerLabelProvider.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/TreeExpansionEvent.class b/Annotation/src/org/eclipse/jface/viewers/TreeExpansionEvent.class
new file mode 100644 (file)
index 0000000..c68ec65
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/TreeExpansionEvent.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/TreeNode.class b/Annotation/src/org/eclipse/jface/viewers/TreeNode.class
new file mode 100644 (file)
index 0000000..fc9a6fb
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/TreeNode.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/TreeNodeContentProvider.class b/Annotation/src/org/eclipse/jface/viewers/TreeNodeContentProvider.class
new file mode 100644 (file)
index 0000000..71d2d6d
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/TreeNodeContentProvider.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/TreePath.class b/Annotation/src/org/eclipse/jface/viewers/TreePath.class
new file mode 100644 (file)
index 0000000..a8f81e4
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/TreePath.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/TreePathViewerSorter$1.class b/Annotation/src/org/eclipse/jface/viewers/TreePathViewerSorter$1.class
new file mode 100644 (file)
index 0000000..c7c665b
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/TreePathViewerSorter$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/TreePathViewerSorter.class b/Annotation/src/org/eclipse/jface/viewers/TreePathViewerSorter.class
new file mode 100644 (file)
index 0000000..ed98fad
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/TreePathViewerSorter.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/TreeSelection$InitializeData.class b/Annotation/src/org/eclipse/jface/viewers/TreeSelection$InitializeData.class
new file mode 100644 (file)
index 0000000..8b04580
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/TreeSelection$InitializeData.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/TreeSelection.class b/Annotation/src/org/eclipse/jface/viewers/TreeSelection.class
new file mode 100644 (file)
index 0000000..b5974b0
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/TreeSelection.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/TreeViewer$1.class b/Annotation/src/org/eclipse/jface/viewers/TreeViewer$1.class
new file mode 100644 (file)
index 0000000..17378db
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/TreeViewer$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/TreeViewer$2.class b/Annotation/src/org/eclipse/jface/viewers/TreeViewer$2.class
new file mode 100644 (file)
index 0000000..cb41936
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/TreeViewer$2.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/TreeViewer$3.class b/Annotation/src/org/eclipse/jface/viewers/TreeViewer$3.class
new file mode 100644 (file)
index 0000000..ce23450
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/TreeViewer$3.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/TreeViewer$4.class b/Annotation/src/org/eclipse/jface/viewers/TreeViewer$4.class
new file mode 100644 (file)
index 0000000..acfde98
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/TreeViewer$4.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/TreeViewer$5.class b/Annotation/src/org/eclipse/jface/viewers/TreeViewer$5.class
new file mode 100644 (file)
index 0000000..2cd1145
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/TreeViewer$5.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/TreeViewer$6.class b/Annotation/src/org/eclipse/jface/viewers/TreeViewer$6.class
new file mode 100644 (file)
index 0000000..1464361
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/TreeViewer$6.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/TreeViewer.class b/Annotation/src/org/eclipse/jface/viewers/TreeViewer.class
new file mode 100644 (file)
index 0000000..60fde98
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/TreeViewer.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/TreeViewerColumn.class b/Annotation/src/org/eclipse/jface/viewers/TreeViewerColumn.class
new file mode 100644 (file)
index 0000000..b825275
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/TreeViewerColumn.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/TreeViewerEditor.class b/Annotation/src/org/eclipse/jface/viewers/TreeViewerEditor.class
new file mode 100644 (file)
index 0000000..5a36135
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/TreeViewerEditor.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/TreeViewerFocusCellManager$1.class b/Annotation/src/org/eclipse/jface/viewers/TreeViewerFocusCellManager$1.class
new file mode 100644 (file)
index 0000000..3cf6d9d
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/TreeViewerFocusCellManager$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/TreeViewerFocusCellManager.class b/Annotation/src/org/eclipse/jface/viewers/TreeViewerFocusCellManager.class
new file mode 100644 (file)
index 0000000..909b446
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/TreeViewerFocusCellManager.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/TreeViewerRow.class b/Annotation/src/org/eclipse/jface/viewers/TreeViewerRow.class
new file mode 100644 (file)
index 0000000..90c756e
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/TreeViewerRow.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/Viewer$1.class b/Annotation/src/org/eclipse/jface/viewers/Viewer$1.class
new file mode 100644 (file)
index 0000000..1c1c323
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/Viewer$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/Viewer$2.class b/Annotation/src/org/eclipse/jface/viewers/Viewer$2.class
new file mode 100644 (file)
index 0000000..17ed7af
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/Viewer$2.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/Viewer.class b/Annotation/src/org/eclipse/jface/viewers/Viewer.class
new file mode 100644 (file)
index 0000000..01b492d
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/Viewer.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ViewerCell.class b/Annotation/src/org/eclipse/jface/viewers/ViewerCell.class
new file mode 100644 (file)
index 0000000..46eda71
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ViewerCell.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ViewerColumn$1.class b/Annotation/src/org/eclipse/jface/viewers/ViewerColumn$1.class
new file mode 100644 (file)
index 0000000..57655af
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ViewerColumn$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ViewerColumn$2.class b/Annotation/src/org/eclipse/jface/viewers/ViewerColumn$2.class
new file mode 100644 (file)
index 0000000..a973e99
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ViewerColumn$2.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ViewerColumn.class b/Annotation/src/org/eclipse/jface/viewers/ViewerColumn.class
new file mode 100644 (file)
index 0000000..783f4cc
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ViewerColumn.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ViewerComparator$1.class b/Annotation/src/org/eclipse/jface/viewers/ViewerComparator$1.class
new file mode 100644 (file)
index 0000000..ba86701
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ViewerComparator$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ViewerComparator.class b/Annotation/src/org/eclipse/jface/viewers/ViewerComparator.class
new file mode 100644 (file)
index 0000000..93cd551
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ViewerComparator.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ViewerDropAdapter.class b/Annotation/src/org/eclipse/jface/viewers/ViewerDropAdapter.class
new file mode 100644 (file)
index 0000000..93de622
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ViewerDropAdapter.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ViewerFilter.class b/Annotation/src/org/eclipse/jface/viewers/ViewerFilter.class
new file mode 100644 (file)
index 0000000..3ecc080
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ViewerFilter.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ViewerLabel.class b/Annotation/src/org/eclipse/jface/viewers/ViewerLabel.class
new file mode 100644 (file)
index 0000000..4d104a4
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ViewerLabel.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ViewerRow.class b/Annotation/src/org/eclipse/jface/viewers/ViewerRow.class
new file mode 100644 (file)
index 0000000..b56558e
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ViewerRow.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/ViewerSorter.class b/Annotation/src/org/eclipse/jface/viewers/ViewerSorter.class
new file mode 100644 (file)
index 0000000..39b774c
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/ViewerSorter.class differ
diff --git a/Annotation/src/org/eclipse/jface/viewers/WrappedViewerLabelProvider.class b/Annotation/src/org/eclipse/jface/viewers/WrappedViewerLabelProvider.class
new file mode 100644 (file)
index 0000000..cf72d46
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/viewers/WrappedViewerLabelProvider.class differ
diff --git a/Annotation/src/org/eclipse/jface/wizard/IWizard.class b/Annotation/src/org/eclipse/jface/wizard/IWizard.class
new file mode 100644 (file)
index 0000000..446a6b5
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/wizard/IWizard.class differ
diff --git a/Annotation/src/org/eclipse/jface/wizard/IWizardContainer.class b/Annotation/src/org/eclipse/jface/wizard/IWizardContainer.class
new file mode 100644 (file)
index 0000000..46049c5
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/wizard/IWizardContainer.class differ
diff --git a/Annotation/src/org/eclipse/jface/wizard/IWizardContainer2.class b/Annotation/src/org/eclipse/jface/wizard/IWizardContainer2.class
new file mode 100644 (file)
index 0000000..bcd0e2f
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/wizard/IWizardContainer2.class differ
diff --git a/Annotation/src/org/eclipse/jface/wizard/IWizardNode.class b/Annotation/src/org/eclipse/jface/wizard/IWizardNode.class
new file mode 100644 (file)
index 0000000..71d71f0
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/wizard/IWizardNode.class differ
diff --git a/Annotation/src/org/eclipse/jface/wizard/IWizardPage.class b/Annotation/src/org/eclipse/jface/wizard/IWizardPage.class
new file mode 100644 (file)
index 0000000..62fc556
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/wizard/IWizardPage.class differ
diff --git a/Annotation/src/org/eclipse/jface/wizard/ProgressMonitorPart$1.class b/Annotation/src/org/eclipse/jface/wizard/ProgressMonitorPart$1.class
new file mode 100644 (file)
index 0000000..730e407
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/wizard/ProgressMonitorPart$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/wizard/ProgressMonitorPart.class b/Annotation/src/org/eclipse/jface/wizard/ProgressMonitorPart.class
new file mode 100644 (file)
index 0000000..898676f
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/wizard/ProgressMonitorPart.class differ
diff --git a/Annotation/src/org/eclipse/jface/wizard/Wizard.class b/Annotation/src/org/eclipse/jface/wizard/Wizard.class
new file mode 100644 (file)
index 0000000..c780b8f
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/wizard/Wizard.class differ
diff --git a/Annotation/src/org/eclipse/jface/wizard/WizardDialog$1.class b/Annotation/src/org/eclipse/jface/wizard/WizardDialog$1.class
new file mode 100644 (file)
index 0000000..5c1ac53
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/wizard/WizardDialog$1.class differ
diff --git a/Annotation/src/org/eclipse/jface/wizard/WizardDialog$2.class b/Annotation/src/org/eclipse/jface/wizard/WizardDialog$2.class
new file mode 100644 (file)
index 0000000..9779854
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/wizard/WizardDialog$2.class differ
diff --git a/Annotation/src/org/eclipse/jface/wizard/WizardDialog$3.class b/Annotation/src/org/eclipse/jface/wizard/WizardDialog$3.class
new file mode 100644 (file)
index 0000000..da1aec3
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/wizard/WizardDialog$3.class differ
diff --git a/Annotation/src/org/eclipse/jface/wizard/WizardDialog$4.class b/Annotation/src/org/eclipse/jface/wizard/WizardDialog$4.class
new file mode 100644 (file)
index 0000000..28a5e25
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/wizard/WizardDialog$4.class differ
diff --git a/Annotation/src/org/eclipse/jface/wizard/WizardDialog$5.class b/Annotation/src/org/eclipse/jface/wizard/WizardDialog$5.class
new file mode 100644 (file)
index 0000000..af899f1
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/wizard/WizardDialog$5.class differ
diff --git a/Annotation/src/org/eclipse/jface/wizard/WizardDialog$6.class b/Annotation/src/org/eclipse/jface/wizard/WizardDialog$6.class
new file mode 100644 (file)
index 0000000..31d44d1
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/wizard/WizardDialog$6.class differ
diff --git a/Annotation/src/org/eclipse/jface/wizard/WizardDialog$PageContainerFillLayout.class b/Annotation/src/org/eclipse/jface/wizard/WizardDialog$PageContainerFillLayout.class
new file mode 100644 (file)
index 0000000..7cc9a15
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/wizard/WizardDialog$PageContainerFillLayout.class differ
diff --git a/Annotation/src/org/eclipse/jface/wizard/WizardDialog.class b/Annotation/src/org/eclipse/jface/wizard/WizardDialog.class
new file mode 100644 (file)
index 0000000..00fb6c5
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/wizard/WizardDialog.class differ
diff --git a/Annotation/src/org/eclipse/jface/wizard/WizardPage.class b/Annotation/src/org/eclipse/jface/wizard/WizardPage.class
new file mode 100644 (file)
index 0000000..90e1f62
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/wizard/WizardPage.class differ
diff --git a/Annotation/src/org/eclipse/jface/wizard/WizardSelectionPage.class b/Annotation/src/org/eclipse/jface/wizard/WizardSelectionPage.class
new file mode 100644 (file)
index 0000000..2343e25
Binary files /dev/null and b/Annotation/src/org/eclipse/jface/wizard/WizardSelectionPage.class differ
diff --git a/Annotation/src/org/eclipse/swt/SWT.class b/Annotation/src/org/eclipse/swt/SWT.class
new file mode 100644 (file)
index 0000000..3c3c03b
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/SWT.class differ
diff --git a/Annotation/src/org/eclipse/swt/SWTError.class b/Annotation/src/org/eclipse/swt/SWTError.class
new file mode 100644 (file)
index 0000000..81a665a
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/SWTError.class differ
diff --git a/Annotation/src/org/eclipse/swt/SWTException.class b/Annotation/src/org/eclipse/swt/SWTException.class
new file mode 100644 (file)
index 0000000..99b2dd7
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/SWTException.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/XPCOM.class b/Annotation/src/org/eclipse/swt/internal/mozilla/XPCOM.class
new file mode 100644 (file)
index 0000000..56e9b95
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/XPCOM.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/XPCOMObject.class b/Annotation/src/org/eclipse/swt/internal/mozilla/XPCOMObject.class
new file mode 100644 (file)
index 0000000..29fb7fb
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/XPCOMObject.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsDynamicFunctionLoad.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsDynamicFunctionLoad.class
new file mode 100644 (file)
index 0000000..d802b8f
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsDynamicFunctionLoad.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsEmbedString.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsEmbedString.class
new file mode 100644 (file)
index 0000000..700b7fe
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsEmbedString.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIAppShell.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIAppShell.class
new file mode 100644 (file)
index 0000000..4ac00e4
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIAppShell.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIAuthInformation.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIAuthInformation.class
new file mode 100644 (file)
index 0000000..6db6f58
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIAuthInformation.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIBaseWindow.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIBaseWindow.class
new file mode 100644 (file)
index 0000000..04588ef
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIBaseWindow.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsICancelable.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsICancelable.class
new file mode 100644 (file)
index 0000000..e3b7714
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsICancelable.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsICategoryManager.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsICategoryManager.class
new file mode 100644 (file)
index 0000000..db4860c
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsICategoryManager.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIChannel.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIChannel.class
new file mode 100644 (file)
index 0000000..e9d5b2a
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIChannel.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIClassInfo.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIClassInfo.class
new file mode 100644 (file)
index 0000000..347b939
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIClassInfo.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIComponentManager.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIComponentManager.class
new file mode 100644 (file)
index 0000000..7395c5d
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIComponentManager.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIComponentRegistrar.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIComponentRegistrar.class
new file mode 100644 (file)
index 0000000..f0239c1
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIComponentRegistrar.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIContextMenuListener.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIContextMenuListener.class
new file mode 100644 (file)
index 0000000..b28ebd0
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIContextMenuListener.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsICookie.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsICookie.class
new file mode 100644 (file)
index 0000000..e9ba855
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsICookie.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsICookieManager.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsICookieManager.class
new file mode 100644 (file)
index 0000000..ebec6f9
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsICookieManager.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsICookieService.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsICookieService.class
new file mode 100644 (file)
index 0000000..eeb6335
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsICookieService.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsICookieService_1_9.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsICookieService_1_9.class
new file mode 100644 (file)
index 0000000..14234a1
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsICookieService_1_9.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsID.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsID.class
new file mode 100644 (file)
index 0000000..1b241db
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsID.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDOMEvent.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDOMEvent.class
new file mode 100644 (file)
index 0000000..c55de24
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDOMEvent.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDOMEventTarget.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDOMEventTarget.class
new file mode 100644 (file)
index 0000000..317f0ea
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDOMEventTarget.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDOMKeyEvent.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDOMKeyEvent.class
new file mode 100644 (file)
index 0000000..1e5eeb2
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDOMKeyEvent.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDOMMouseEvent.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDOMMouseEvent.class
new file mode 100644 (file)
index 0000000..8113e96
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDOMMouseEvent.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDOMSerializer.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDOMSerializer.class
new file mode 100644 (file)
index 0000000..c86a914
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDOMSerializer.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDOMSerializer_1_7.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDOMSerializer_1_7.class
new file mode 100644 (file)
index 0000000..16658b8
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDOMSerializer_1_7.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDOMUIEvent.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDOMUIEvent.class
new file mode 100644 (file)
index 0000000..f42af3a
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDOMUIEvent.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDOMWindow.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDOMWindow.class
new file mode 100644 (file)
index 0000000..016a4a5
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDOMWindow.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDOMWindowCollection.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDOMWindowCollection.class
new file mode 100644 (file)
index 0000000..23e73da
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDOMWindowCollection.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDataType.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDataType.class
new file mode 100644 (file)
index 0000000..dfea513
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDataType.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDirectoryService.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDirectoryService.class
new file mode 100644 (file)
index 0000000..62c77b3
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDirectoryService.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDirectoryServiceProvider.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDirectoryServiceProvider.class
new file mode 100644 (file)
index 0000000..6aa81ad
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDirectoryServiceProvider.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDirectoryServiceProvider2.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDirectoryServiceProvider2.class
new file mode 100644 (file)
index 0000000..20f5018
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDirectoryServiceProvider2.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDocShell.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDocShell.class
new file mode 100644 (file)
index 0000000..7d34822
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDocShell.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDocShell_1_8.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDocShell_1_8.class
new file mode 100644 (file)
index 0000000..9275514
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDocShell_1_8.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDownload.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDownload.class
new file mode 100644 (file)
index 0000000..243014b
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDownload.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDownload_1_8.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDownload_1_8.class
new file mode 100644 (file)
index 0000000..bbfd321
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIDownload_1_8.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIEmbeddingSiteWindow.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIEmbeddingSiteWindow.class
new file mode 100644 (file)
index 0000000..d6e03c3
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIEmbeddingSiteWindow.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIFactory.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIFactory.class
new file mode 100644 (file)
index 0000000..b23809a
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIFactory.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIFile.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIFile.class
new file mode 100644 (file)
index 0000000..a56fb64
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIFile.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIFilePicker.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIFilePicker.class
new file mode 100644 (file)
index 0000000..438c84c
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIFilePicker.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIFilePicker_1_8.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIFilePicker_1_8.class
new file mode 100644 (file)
index 0000000..d44c1f6
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIFilePicker_1_8.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIHelperAppLauncher.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIHelperAppLauncher.class
new file mode 100644 (file)
index 0000000..57cd4fd
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIHelperAppLauncher.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIHelperAppLauncherDialog.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIHelperAppLauncherDialog.class
new file mode 100644 (file)
index 0000000..66abeea
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIHelperAppLauncherDialog.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIHelperAppLauncherDialog_1_9.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIHelperAppLauncherDialog_1_9.class
new file mode 100644 (file)
index 0000000..8298882
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIHelperAppLauncherDialog_1_9.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIHelperAppLauncher_1_8.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIHelperAppLauncher_1_8.class
new file mode 100644 (file)
index 0000000..ab75d99
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIHelperAppLauncher_1_8.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIHelperAppLauncher_1_9.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIHelperAppLauncher_1_9.class
new file mode 100644 (file)
index 0000000..7bad12f
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIHelperAppLauncher_1_9.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIIOService.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIIOService.class
new file mode 100644 (file)
index 0000000..21f2103
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIIOService.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIInputStream.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIInputStream.class
new file mode 100644 (file)
index 0000000..8af96b0
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIInputStream.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIInterfaceRequestor.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIInterfaceRequestor.class
new file mode 100644 (file)
index 0000000..e7ead38
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIInterfaceRequestor.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIJSContextStack.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIJSContextStack.class
new file mode 100644 (file)
index 0000000..58e3a67
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIJSContextStack.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsILocalFile.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsILocalFile.class
new file mode 100644 (file)
index 0000000..3ee4642
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsILocalFile.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIMemory.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIMemory.class
new file mode 100644 (file)
index 0000000..d30f3b8
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIMemory.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIObserverService.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIObserverService.class
new file mode 100644 (file)
index 0000000..9f48c64
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIObserverService.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIPrefBranch.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIPrefBranch.class
new file mode 100644 (file)
index 0000000..05ae8bb
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIPrefBranch.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIPrefLocalizedString.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIPrefLocalizedString.class
new file mode 100644 (file)
index 0000000..db3a8ce
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIPrefLocalizedString.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIPrefService.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIPrefService.class
new file mode 100644 (file)
index 0000000..23c6f81
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIPrefService.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIPrincipal.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIPrincipal.class
new file mode 100644 (file)
index 0000000..e10b9a2
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIPrincipal.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIProgressDialog.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIProgressDialog.class
new file mode 100644 (file)
index 0000000..c646543
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIProgressDialog.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIProgressDialog_1_8.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIProgressDialog_1_8.class
new file mode 100644 (file)
index 0000000..d3ee6b5
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIProgressDialog_1_8.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIPromptService.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIPromptService.class
new file mode 100644 (file)
index 0000000..983a740
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIPromptService.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIPromptService2.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIPromptService2.class
new file mode 100644 (file)
index 0000000..c8213df
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIPromptService2.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIProperties.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIProperties.class
new file mode 100644 (file)
index 0000000..08aeee5
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIProperties.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIRequest.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIRequest.class
new file mode 100644 (file)
index 0000000..1e10d89
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIRequest.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIScriptSecurityManager_1_9.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIScriptSecurityManager_1_9.class
new file mode 100644 (file)
index 0000000..8bd8ea6
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIScriptSecurityManager_1_9.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIScriptSecurityManager_1_9_1.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIScriptSecurityManager_1_9_1.class
new file mode 100644 (file)
index 0000000..a3ed690
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIScriptSecurityManager_1_9_1.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsISecurityCheckedComponent.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsISecurityCheckedComponent.class
new file mode 100644 (file)
index 0000000..759a76b
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsISecurityCheckedComponent.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsISerializable.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsISerializable.class
new file mode 100644 (file)
index 0000000..13b3037
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsISerializable.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIServiceManager.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIServiceManager.class
new file mode 100644 (file)
index 0000000..1bf9c91
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIServiceManager.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsISimpleEnumerator.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsISimpleEnumerator.class
new file mode 100644 (file)
index 0000000..12ee7fe
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsISimpleEnumerator.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsISupports.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsISupports.class
new file mode 100644 (file)
index 0000000..6f70471
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsISupports.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsISupportsWeakReference.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsISupportsWeakReference.class
new file mode 100644 (file)
index 0000000..eef3fe0
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsISupportsWeakReference.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsITooltipListener.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsITooltipListener.class
new file mode 100644 (file)
index 0000000..b0843a4
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsITooltipListener.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsITransfer.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsITransfer.class
new file mode 100644 (file)
index 0000000..ae12b7e
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsITransfer.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIURI.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIURI.class
new file mode 100644 (file)
index 0000000..3e0d315
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIURI.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIURIContentListener.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIURIContentListener.class
new file mode 100644 (file)
index 0000000..0a82d6b
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIURIContentListener.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIVariant.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIVariant.class
new file mode 100644 (file)
index 0000000..9ae5b3c
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIVariant.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWeakReference.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWeakReference.class
new file mode 100644 (file)
index 0000000..a474c58
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWeakReference.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWebBrowser.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWebBrowser.class
new file mode 100644 (file)
index 0000000..6403628
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWebBrowser.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWebBrowserChrome.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWebBrowserChrome.class
new file mode 100644 (file)
index 0000000..a77dbd4
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWebBrowserChrome.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWebBrowserChromeFocus.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWebBrowserChromeFocus.class
new file mode 100644 (file)
index 0000000..3e96160
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWebBrowserChromeFocus.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWebBrowserFocus.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWebBrowserFocus.class
new file mode 100644 (file)
index 0000000..e0d5bf2
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWebBrowserFocus.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWebBrowserSetup.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWebBrowserSetup.class
new file mode 100644 (file)
index 0000000..9222514
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWebBrowserSetup.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWebBrowserStream.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWebBrowserStream.class
new file mode 100644 (file)
index 0000000..f7a2412
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWebBrowserStream.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWebNavigation.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWebNavigation.class
new file mode 100644 (file)
index 0000000..6a2e287
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWebNavigation.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWebNavigationInfo.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWebNavigationInfo.class
new file mode 100644 (file)
index 0000000..d3f1acf
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWebNavigationInfo.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWebProgress.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWebProgress.class
new file mode 100644 (file)
index 0000000..974dfe2
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWebProgress.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWebProgressListener.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWebProgressListener.class
new file mode 100644 (file)
index 0000000..41a1195
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWebProgressListener.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWebProgressListener2.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWebProgressListener2.class
new file mode 100644 (file)
index 0000000..b4fcddd
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWebProgressListener2.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWindowCreator.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWindowCreator.class
new file mode 100644 (file)
index 0000000..a4fa617
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWindowCreator.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWindowCreator2.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWindowCreator2.class
new file mode 100644 (file)
index 0000000..138990d
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWindowCreator2.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWindowWatcher.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWindowWatcher.class
new file mode 100644 (file)
index 0000000..a44914d
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWindowWatcher.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWritableVariant.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWritableVariant.class
new file mode 100644 (file)
index 0000000..cfe3ee5
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIWritableVariant.class differ
diff --git a/Annotation/src/org/eclipse/swt/internal/mozilla/nsIXPCSecurityManager.class b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIXPCSecurityManager.class
new file mode 100644 (file)
index 0000000..5aa5b58
Binary files /dev/null and b/Annotation/src/org/eclipse/swt/internal/mozilla/nsIXPCSecurityManager.class differ
diff --git a/Annotation/version.txt b/Annotation/version.txt
new file mode 100644 (file)
index 0000000..d6761c7
--- /dev/null
@@ -0,0 +1 @@
+version 3.550
\ No newline at end of file