diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/MediaViewImagePanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/MediaViewImagePanel.java index 6872aace78..cf8fd11741 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/MediaViewImagePanel.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/MediaViewImagePanel.java @@ -22,6 +22,7 @@ import java.awt.Dimension; import java.awt.EventQueue; import java.awt.image.BufferedImage; import java.io.BufferedInputStream; +import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.util.Collections; @@ -174,6 +175,9 @@ public class MediaViewImagePanel extends JPanel implements DataContentViewerMedi borderpane.setCenter(fxImageView); } } + } catch (EOFException ex) { + LOGGER.log(Level.WARNING, "Could not load image file into media view (EOF): {0}", file.getName()); //NON-NLS + borderpane.setCenter(errorLabel); } catch (IllegalArgumentException | IOException ex) { LOGGER.log(Level.WARNING, "Could not load image file into media view: " + file.getName(), ex); //NON-NLS borderpane.setCenter(errorLabel); diff --git a/Core/src/org/sleuthkit/autopsy/coreutils/ImageUtils.java b/Core/src/org/sleuthkit/autopsy/coreutils/ImageUtils.java index c9e337a29c..d44111a231 100755 --- a/Core/src/org/sleuthkit/autopsy/coreutils/ImageUtils.java +++ b/Core/src/org/sleuthkit/autopsy/coreutils/ImageUtils.java @@ -26,6 +26,7 @@ import com.google.common.io.Files; import java.awt.Image; import java.awt.image.BufferedImage; import java.io.BufferedInputStream; +import java.io.EOFException; import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -135,8 +136,8 @@ public class ImageUtils { /** * thread that saves generated thumbnails to disk in the background */ - private static final Executor imageSaver - = Executors.newSingleThreadExecutor(new BasicThreadFactory.Builder() + private static final Executor imageSaver = + Executors.newSingleThreadExecutor(new BasicThreadFactory.Builder() .namingPattern("icon saver-%d").build()); public static List getSupportedImageExtensions() { @@ -524,14 +525,13 @@ public class ImageUtils { return ScalrWrapper.cropImage(bi, Math.min(iconSize, bi.getWidth()), Math.min(iconSize, bi.getHeight())); } } catch (OutOfMemoryError e) { - LOGGER.log(Level.WARNING, "Could not scale image (too large): " + content.getName(), e); //NON-NLS - - return null; + LOGGER.log(Level.WARNING, "Could not scale image (too large) " + content.getName(), e); //NON-NLS + } catch (EOFException e) { + LOGGER.log(Level.WARNING, "Could not load image (EOF) {0}", content.getName()); //NON-NLS } catch (Exception e) { - LOGGER.log(Level.WARNING, "Could not load image: " + content.getName(), e); //NON-NLS - return null; - + LOGGER.log(Level.WARNING, "Could not load image " + content.getName(), e); //NON-NLS } + return null; } } diff --git a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/ImageGalleryController.java b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/ImageGalleryController.java index 395349cbce..2b472ac422 100644 --- a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/ImageGalleryController.java +++ b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/ImageGalleryController.java @@ -49,10 +49,12 @@ import javafx.scene.layout.CornerRadii; import javafx.scene.layout.Region; import javafx.scene.layout.StackPane; import javafx.scene.paint.Color; +import javax.annotation.Nullable; import javax.swing.SwingUtilities; import org.apache.commons.lang3.StringUtils; import org.netbeans.api.progress.ProgressHandle; import org.netbeans.api.progress.ProgressHandleFactory; +import org.openide.util.Cancellable; import org.openide.util.Exceptions; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.events.ContentTagAddedEvent; @@ -395,6 +397,9 @@ public final class ImageGalleryController { tagsManager.clearFollowUpTagName(); tagsManager.unregisterListener(groupManager); tagsManager.unregisterListener(categoryManager); + dbWorkerThread.cancelAllTasks(); + dbWorkerThread = null; + restartWorker(); Toolbar.getDefault(this).reset(); groupManager.clear(); @@ -418,7 +423,12 @@ public final class ImageGalleryController { dbWorkerThread.addTask(innerTask); } + @Nullable synchronized public DrawableFile getFileFromId(Long fileID) throws TskCoreException { + if (Objects.isNull(db)) { + LOGGER.log(Level.WARNING, "Could not get file from id, no DB set. The case is probably closed."); + return null; + } return db.getFileFromID(fileID); } @@ -587,7 +597,7 @@ public final class ImageGalleryController { try { InnerTask it = workQueue.take(); - if (it.cancelled == false) { + if (it.isCancelled() == false) { it.run(); } @@ -609,7 +619,7 @@ public final class ImageGalleryController { /** * Abstract base class for task to be done on {@link DBWorkerThread} */ - static public abstract class InnerTask implements Runnable { + static public abstract class InnerTask implements Runnable, Cancellable { public double getProgress() { return progress.get(); @@ -653,13 +663,13 @@ public final class ImageGalleryController { protected InnerTask() { } - protected volatile boolean cancelled = false; - - public void cancel() { + @Override + synchronized public boolean cancel() { updateState(Worker.State.CANCELLED); + return true; } - protected boolean isCancelled() { + synchronized protected boolean isCancelled() { return getState() == Worker.State.CANCELLED; } } @@ -693,7 +703,7 @@ public final class ImageGalleryController { */ static private class UpdateFileTask extends FileTask { - public UpdateFileTask(AbstractFile f, DrawableDB taskDB) { + UpdateFileTask(AbstractFile f, DrawableDB taskDB) { super(f, taskDB); } @@ -720,7 +730,7 @@ public final class ImageGalleryController { */ static private class RemoveFileTask extends FileTask { - public RemoveFileTask(AbstractFile f, DrawableDB taskDB) { + RemoveFileTask(AbstractFile f, DrawableDB taskDB) { super(f, taskDB); } @@ -756,7 +766,7 @@ public final class ImageGalleryController { private final DrawableDB taskDB; private final SleuthkitCase tskCase; - public CopyAnalyzedFiles(ImageGalleryController controller, DrawableDB taskDB, SleuthkitCase tskCase) { + CopyAnalyzedFiles(ImageGalleryController controller, DrawableDB taskDB, SleuthkitCase tskCase) { this.controller = controller; this.taskDB = taskDB; this.tskCase = tskCase; @@ -766,8 +776,8 @@ public final class ImageGalleryController { + StringUtils.join(FileTypeUtils.getAllSupportedExtensions(), "' or name LIKE '%.") + "')"; - static private final String MIMETYPE_CLAUSE - = "blackboard_attributes.value_text LIKE '" + static private final String MIMETYPE_CLAUSE = + "blackboard_attributes.value_text LIKE '" + StringUtils.join(FileTypeUtils.getAllSupportedMimeTypes(), "' OR blackboard_attributes.value_text LIKE '") + "' "; @@ -801,7 +811,7 @@ public final class ImageGalleryController { DrawableDB.DrawableTransaction tr = taskDB.beginTransaction(); int units = 0; for (final AbstractFile f : files) { - if (cancelled) { + if (isCancelled()) { LOGGER.log(Level.WARNING, "task cancelled: not all contents may be transfered to database"); progressHandle.finish(); break; @@ -848,12 +858,12 @@ public final class ImageGalleryController { } catch (TskCoreException ex) { Logger.getLogger(CopyAnalyzedFiles.class.getName()).log(Level.WARNING, "failed to transfer all database contents", ex); - } - + } progressHandle.finish(); updateMessage(""); updateProgress(-1.0); + controller.setStale(false); } } @@ -877,13 +887,13 @@ public final class ImageGalleryController { // (name like '.jpg' or name like '.png' ...) private final String DRAWABLE_QUERY = "(name LIKE '%." + StringUtils.join(FileTypeUtils.getAllSupportedExtensions(), "' OR name LIKE '%.") + "') "; - private ProgressHandle progressHandle = ProgressHandleFactory.createHandle("prepopulating image/video database"); + private ProgressHandle progressHandle = ProgressHandleFactory.createHandle("prepopulating image/video database", this); /** * * @param dataSourceId Data source object ID */ - public PrePopulateDataSourceFiles(Content dataSource) { + PrePopulateDataSourceFiles(Content dataSource) { super(); this.dataSource = dataSource; } @@ -933,7 +943,7 @@ public final class ImageGalleryController { DrawableDB.DrawableTransaction tr = db.beginTransaction(); int units = 0; for (final AbstractFile f : files) { - if (cancelled) { + if (isCancelled()) { LOGGER.log(Level.WARNING, "task cancelled: not all contents may be transfered to database"); progressHandle.finish(); break; @@ -951,7 +961,7 @@ public final class ImageGalleryController { } catch (TskCoreException ex) { Logger.getLogger(PrePopulateDataSourceFiles.class.getName()).log(Level.WARNING, "failed to transfer all database contents", ex); - } + } progressHandle.finish(); } diff --git a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/ImageGalleryOptionsPanelController.java b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/ImageGalleryOptionsPanelController.java index 78ed75fe6d..28d507619e 100644 --- a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/ImageGalleryOptionsPanelController.java +++ b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/ImageGalleryOptionsPanelController.java @@ -31,7 +31,7 @@ import org.openide.util.Lookup; */ @OptionsPanelController.TopLevelRegistration( categoryName = "#OptionsCategory_Name_Options", - iconBase = "org/sleuthkit/autopsy/imagegallery/images/polaroid_48_silhouette.png", + iconBase = "org/sleuthkit/autopsy/imagegallery/images/polaroid_32_silhouette.png", keywords = "#OptionsCategory_Keywords_Options", keywordsCategory = "Options", position = 10 diff --git a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/drawableviews/DrawableUIBase.java b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/drawableviews/DrawableUIBase.java index f238e454b1..6983f49180 100644 --- a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/drawableviews/DrawableUIBase.java +++ b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/gui/drawableviews/DrawableUIBase.java @@ -89,7 +89,7 @@ abstract public class DrawableUIBase extends AnchorPane implements DrawableView return fileOpt; } else { try { - fileOpt = Optional.of(getController().getFileFromId(fileIDOpt.get())); + fileOpt = Optional.ofNullable(getController().getFileFromId(fileIDOpt.get())); } catch (TskCoreException ex) { Logger.getAnonymousLogger().log(Level.WARNING, "failed to get DrawableFile for obj_id" + fileIDOpt.get(), ex); fileOpt = Optional.empty(); @@ -206,7 +206,6 @@ abstract public class DrawableUIBase extends AnchorPane implements DrawableView super.failed(); LOGGER.log(Level.SEVERE, "Failed to cache content for" + file.getName(), getException()); } - abstract void saveToCache(X result); } diff --git a/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/images/polaroid_32_silhouette.png b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/images/polaroid_32_silhouette.png new file mode 100644 index 0000000000..aa203a1270 Binary files /dev/null and b/ImageGallery/src/org/sleuthkit/autopsy/imagegallery/images/polaroid_32_silhouette.png differ