From 80abec5f13ff92c73bfc910a195f3deb646bc9aa Mon Sep 17 00:00:00 2001 From: millmanorama Date: Tue, 21 Mar 2017 13:45:21 +0100 Subject: [PATCH 1/3] resize loaded gifs --- .../autopsy/coreutils/ImageUtils.java | 32 ++++++++++++------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/coreutils/ImageUtils.java b/Core/src/org/sleuthkit/autopsy/coreutils/ImageUtils.java index b80642ee43..6f2dd5e77e 100755 --- a/Core/src/org/sleuthkit/autopsy/coreutils/ImageUtils.java +++ b/Core/src/org/sleuthkit/autopsy/coreutils/ImageUtils.java @@ -160,7 +160,7 @@ public class ImageUtils { private static FileTypeDetector fileTypeDetector; /** - *Thread/Executor that saves generated thumbnails to disk in the background + * Thread/Executor that saves generated thumbnails to disk in the background */ private static final Executor imageSaver = Executors.newSingleThreadExecutor(new BasicThreadFactory.Builder() @@ -303,14 +303,22 @@ public class ImageUtils { public static BufferedImage getThumbnail(Content content, int iconSize) { if (content instanceof AbstractFile) { AbstractFile file = (AbstractFile) content; - - Task thumbnailTask = newGetThumbnailTask(file, iconSize, true); - thumbnailTask.run(); - try { - return SwingFXUtils.fromFXImage(thumbnailTask.get(), null); - } catch (InterruptedException | ExecutionException ex) { - LOGGER.log(Level.WARNING, "Failed to get thumbnail for " + getContentPathSafe(content), ex); //NON-NLS - return DEFAULT_THUMBNAIL; + if (ImageUtils.isGIF(file)) { + try { + return ScalrWrapper.resizeHighQuality(ImageIO.read(new BufferedInputStream(new ReadContentInputStream(file))), iconSize, iconSize); + } catch (IOException iOException) { + LOGGER.log(Level.WARNING, "Failed to get thumbnail for " + getContentPathSafe(content), iOException); //NON-NLS + return DEFAULT_THUMBNAIL; + } + } else { + Task thumbnailTask = newGetThumbnailTask(file, iconSize, true); + thumbnailTask.run(); + try { + return SwingFXUtils.fromFXImage(thumbnailTask.get(), null); + } catch (InterruptedException | ExecutionException ex) { + LOGGER.log(Level.WARNING, "Failed to get thumbnail for " + getContentPathSafe(content), ex); //NON-NLS + return DEFAULT_THUMBNAIL; + } } } else { return DEFAULT_THUMBNAIL; @@ -334,12 +342,12 @@ public class ImageUtils { } /** - * Get the location of the cached thumbnail for a file with the given fileID - * as a java File. The returned File may not exist on disk yet. + * Get the location,as a java File, of the cached thumbnail for an file with + * the given fileID . The returned File may not exist on disk yet. * * @param fileID the fileID to get the cached thumbnail location for * - * @return a File object representing the location of the cached thumbnail. + * @return A File object representing the location of the cached thumbnail. * This file may not actually exist(yet). Returns null if there was * any problem getting the file, such as no case was open. */ From 46ca7ee6a1ff644a4a23686e03a13cf718aedcce Mon Sep 17 00:00:00 2001 From: millmanorama Date: Wed, 22 Mar 2017 11:30:43 +0100 Subject: [PATCH 2/3] introduce getBufferedReadContentStream, comments --- .../autopsy/coreutils/ImageUtils.java | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/coreutils/ImageUtils.java b/Core/src/org/sleuthkit/autopsy/coreutils/ImageUtils.java index 6f2dd5e77e..3c508f0304 100755 --- a/Core/src/org/sleuthkit/autopsy/coreutils/ImageUtils.java +++ b/Core/src/org/sleuthkit/autopsy/coreutils/ImageUtils.java @@ -297,15 +297,19 @@ public class ImageUtils { * @param content the content to generate a thumbnail for * @param iconSize the size (one side of a square) in pixels to generate * - * @return a thumbnail for the given image or a default one if there was a + * @return A thumbnail for the given image or a default one if there was a * problem making a thumbnail. */ public static BufferedImage getThumbnail(Content content, int iconSize) { if (content instanceof AbstractFile) { AbstractFile file = (AbstractFile) content; if (ImageUtils.isGIF(file)) { + /* + * Intercepting the image reading code for GIFs here allows us + * to rescale easily, but we lose animations. + */ try { - return ScalrWrapper.resizeHighQuality(ImageIO.read(new BufferedInputStream(new ReadContentInputStream(file))), iconSize, iconSize); + return ScalrWrapper.resizeHighQuality(ImageIO.read(getBufferedReadContentStream(file)), iconSize, iconSize); } catch (IOException iOException) { LOGGER.log(Level.WARNING, "Failed to get thumbnail for " + getContentPathSafe(content), iOException); //NON-NLS return DEFAULT_THUMBNAIL; @@ -325,6 +329,19 @@ public class ImageUtils { } } + /** + * Get a BufferedInputStream wrapped around a ReadContentStream for the + * given AbstractFile. + * + * @param file The AbstractFile to get a stream for. + * + * @return A BufferedInputStream wrapped around a ReadContentStream for the + * given AbstractFile + */ + private static BufferedInputStream getBufferedReadContentStream(AbstractFile file) { + return new BufferedInputStream(new ReadContentInputStream(file)); + } + /** * Get a thumbnail of a specified size for the given image. Generates the * thumbnail if it is not already cached. @@ -550,7 +567,7 @@ public class ImageUtils { * @see #getImageHeight(org.sleuthkit.datamodel.AbstractFile) */ private static T getImageProperty(AbstractFile file, final String errorTemplate, PropertyExtractor propertyExtractor) throws IOException { - try (InputStream inputStream = new BufferedInputStream(new ReadContentInputStream(file));) { + try (InputStream inputStream = getBufferedReadContentStream(file);) { try (ImageInputStream input = ImageIO.createImageInputStream(inputStream)) { if (input == null) { IIOException iioException = new IIOException("Could not create ImageInputStream."); @@ -793,7 +810,7 @@ public class ImageUtils { protected javafx.scene.image.Image readImage() throws IOException { if (ImageUtils.isGIF(file)) { //use JavaFX to directly read GIF to preserve potential animation - javafx.scene.image.Image image = new javafx.scene.image.Image(new BufferedInputStream(new ReadContentInputStream(file))); + javafx.scene.image.Image image = new javafx.scene.image.Image(getBufferedReadContentStream(file)); if (image.isError() == false) { return image; } From b981923546e6738ad7a7645ea8fc820436dfd85d Mon Sep 17 00:00:00 2001 From: millmanorama Date: Wed, 22 Mar 2017 11:54:10 +0100 Subject: [PATCH 3/3] refactor getThumbnail to reduce if/else clutter --- .../autopsy/coreutils/ImageUtils.java | 78 +++++++++---------- 1 file changed, 38 insertions(+), 40 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/coreutils/ImageUtils.java b/Core/src/org/sleuthkit/autopsy/coreutils/ImageUtils.java index 3c508f0304..42c11fa2fa 100755 --- a/Core/src/org/sleuthkit/autopsy/coreutils/ImageUtils.java +++ b/Core/src/org/sleuthkit/autopsy/coreutils/ImageUtils.java @@ -308,25 +308,26 @@ public class ImageUtils { * Intercepting the image reading code for GIFs here allows us * to rescale easily, but we lose animations. */ - try { - return ScalrWrapper.resizeHighQuality(ImageIO.read(getBufferedReadContentStream(file)), iconSize, iconSize); + try (BufferedInputStream bufferedReadContentStream = getBufferedReadContentStream(file);) { + final BufferedImage image = ImageIO.read(bufferedReadContentStream); + if (image != null) { + return ScalrWrapper.resizeHighQuality(image, iconSize, iconSize); + } } catch (IOException iOException) { LOGGER.log(Level.WARNING, "Failed to get thumbnail for " + getContentPathSafe(content), iOException); //NON-NLS - return DEFAULT_THUMBNAIL; - } - } else { - Task thumbnailTask = newGetThumbnailTask(file, iconSize, true); - thumbnailTask.run(); - try { - return SwingFXUtils.fromFXImage(thumbnailTask.get(), null); - } catch (InterruptedException | ExecutionException ex) { - LOGGER.log(Level.WARNING, "Failed to get thumbnail for " + getContentPathSafe(content), ex); //NON-NLS - return DEFAULT_THUMBNAIL; } + return DEFAULT_THUMBNAIL; + } + + Task thumbnailTask = newGetThumbnailTask(file, iconSize, true); + thumbnailTask.run(); + try { + return SwingFXUtils.fromFXImage(thumbnailTask.get(), null); + } catch (InterruptedException | ExecutionException ex) { + LOGGER.log(Level.WARNING, "Failed to get thumbnail for " + getContentPathSafe(content), ex); //NON-NLS } - } else { - return DEFAULT_THUMBNAIL; } + return DEFAULT_THUMBNAIL; } /** @@ -567,33 +568,30 @@ public class ImageUtils { * @see #getImageHeight(org.sleuthkit.datamodel.AbstractFile) */ private static T getImageProperty(AbstractFile file, final String errorTemplate, PropertyExtractor propertyExtractor) throws IOException { - try (InputStream inputStream = getBufferedReadContentStream(file);) { - try (ImageInputStream input = ImageIO.createImageInputStream(inputStream)) { - if (input == null) { - IIOException iioException = new IIOException("Could not create ImageInputStream."); - LOGGER.log(Level.WARNING, errorTemplate + iioException.toString(), getContentPathSafe(file)); - throw iioException; - } - Iterator readers = ImageIO.getImageReaders(input); - - if (readers.hasNext()) { - ImageReader reader = readers.next(); - reader.setInput(input); - try { - - return propertyExtractor.extract(reader); - } catch (IOException ex) { - LOGGER.log(Level.WARNING, errorTemplate + ex.toString(), getContentPathSafe(file)); - throw ex; - } finally { - reader.dispose(); - } - } else { - IIOException iioException = new IIOException("No ImageReader found."); - LOGGER.log(Level.WARNING, errorTemplate + iioException.toString(), getContentPathSafe(file)); - - throw iioException; + try (InputStream inputStream = getBufferedReadContentStream(file); + ImageInputStream input = ImageIO.createImageInputStream(inputStream)) { + if (input == null) { + IIOException iioException = new IIOException("Could not create ImageInputStream."); + LOGGER.log(Level.WARNING, errorTemplate + iioException.toString(), getContentPathSafe(file)); + throw iioException; + } + Iterator readers = ImageIO.getImageReaders(input); + + if (readers.hasNext()) { + ImageReader reader = readers.next(); + reader.setInput(input); + try { + return propertyExtractor.extract(reader); + } catch (IOException ex) { + LOGGER.log(Level.WARNING, errorTemplate + ex.toString(), getContentPathSafe(file)); + throw ex; + } finally { + reader.dispose(); } + } else { + IIOException iioException = new IIOException("No ImageReader found."); + LOGGER.log(Level.WARNING, errorTemplate + iioException.toString(), getContentPathSafe(file)); + throw iioException; } } }