From ea0cdffe1c3de94556f43f4c31b93ad7f133bdb6 Mon Sep 17 00:00:00 2001 From: jmillman Date: Thu, 30 Jul 2015 11:30:46 -0400 Subject: [PATCH 1/5] only show application/octet-stream if the file has a supported extension --- .../corecomponents/MediaViewImagePanel.java | 20 +++++++++++++++++-- .../autopsy/coreutils/ImageUtils.java | 7 ++++--- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/MediaViewImagePanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/MediaViewImagePanel.java index 2a6de774f9..1e7e21e35b 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/MediaViewImagePanel.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/MediaViewImagePanel.java @@ -47,8 +47,10 @@ import org.sleuthkit.autopsy.coreutils.ImageUtils; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; import org.sleuthkit.autopsy.coreutils.ThreadConfined; +import org.sleuthkit.autopsy.modules.filetypeid.FileTypeDetector; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.ReadContentInputStream; +import org.sleuthkit.datamodel.TskCoreException; /** * Image viewer part of the Media View layered pane. Uses JavaFX to display the @@ -220,8 +222,22 @@ public class MediaViewImagePanel extends JPanel implements DataContentViewerMedi @Override public boolean isSupported(AbstractFile file) { - return DataContentViewerMedia.MediaViewPanel.super.isSupported(file) - || ImageUtils.hasImageFileHeader(file); + if (DataContentViewerMedia.MediaViewPanel.super.isSupported(file)) { + return true; + } else { + String extension = file.getNameExtension(); + try { + String mimeType = new FileTypeDetector().getFileType(file); + + return (mimeType.equalsIgnoreCase("audio/x-aiff") && "iff".equalsIgnoreCase(extension)) + || (mimeType.equalsIgnoreCase("application/octet-stream") && getExtensionsList().contains(extension)); + + } catch (FileTypeDetector.FileTypeDetectorInitException | TskCoreException ex) { + LOGGER.log(Level.WARNING, "Failed to get mime type for file", ex); + } + + return ImageUtils.thumbnailSupported(file); + } } /** diff --git a/Core/src/org/sleuthkit/autopsy/coreutils/ImageUtils.java b/Core/src/org/sleuthkit/autopsy/coreutils/ImageUtils.java index 77e8dfb42d..fbf9531431 100755 --- a/Core/src/org/sleuthkit/autopsy/coreutils/ImageUtils.java +++ b/Core/src/org/sleuthkit/autopsy/coreutils/ImageUtils.java @@ -138,6 +138,7 @@ public class ImageUtils { "image/x-rgb", "image/x-ms-bmp", "application/x-123")); + SUPPORTED_IMAGE_MIME_TYPES.removeIf("application/octet-stream"::equals); SUPPORTED_MIME_TYPES.addAll(SUPPORTED_IMAGE_MIME_TYPES); SUPPORTED_MIME_TYPES.addAll(SUPPORTED_VIDEO_MIME_TYPES); @@ -228,12 +229,13 @@ public class ImageUtils { return false; } AbstractFile file = (AbstractFile) content; - + final String extension = file.getNameExtension(); try { String mimeType = getFileTypeDetector().getFileType(file); if (Objects.nonNull(mimeType)) { return SUPPORTED_MIME_TYPES.contains(mimeType) - || (mimeType.equalsIgnoreCase("audio/x-aiff") && "iff".equalsIgnoreCase(file.getNameExtension())); + || (mimeType.equalsIgnoreCase("audio/x-aiff") && "iff".equalsIgnoreCase(file.getNameExtension())) + || (mimeType.equalsIgnoreCase("application/octet-stream") && SUPPORTED_EXTENSIONS.contains(extension)); } } catch (FileTypeDetector.FileTypeDetectorInitException | TskCoreException ex) { LOGGER.log(Level.WARNING, "Failed to look up mimetype for " + file.getName() + " using FileTypeDetector. Fallingback on AbstractFile.isMimeType", ex); @@ -247,7 +249,6 @@ public class ImageUtils { } // if we have an extension, check it - final String extension = file.getNameExtension(); if (StringUtils.isNotBlank(extension) && SUPPORTED_EXTENSIONS.contains(extension)) { return true; } From 240a46221c873ca7b425c1a3d423ab9321d71b0b Mon Sep 17 00:00:00 2001 From: jmillman Date: Thu, 30 Jul 2015 12:38:50 -0400 Subject: [PATCH 2/5] refactor isSupportedLogic to provide a clearer distinction between video and images while reusing more code. --- .../autopsy/coreutils/ImageUtils.java | 152 ++++++++---------- .../autopsy/coreutils/VideoUtils.java | 38 +++++ 2 files changed, 106 insertions(+), 84 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/coreutils/ImageUtils.java b/Core/src/org/sleuthkit/autopsy/coreutils/ImageUtils.java index fbf9531431..7e6fc57304 100755 --- a/Core/src/org/sleuthkit/autopsy/coreutils/ImageUtils.java +++ b/Core/src/org/sleuthkit/autopsy/coreutils/ImageUtils.java @@ -30,7 +30,6 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.nio.file.Paths; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -74,26 +73,11 @@ public class ImageUtils { private static final Logger logger = LOGGER; private static final BufferedImage DEFAULT_THUMBNAIL; - private static final TreeSet SUPPORTED_MIME_TYPES = new TreeSet<>(); - private static final List SUPPORTED_EXTENSIONS = new ArrayList<>(); + private static final List SUPPORTED_IMAGE_EXTENSIONS; - private static final List SUPPORTED_VIDEO_EXTENSIONS - = Arrays.asList("mov", "m4v", "flv", "mp4", "3gp", "avi", "mpg", - "mpeg", "asf", "divx", "rm", "moov", "wmv", "vob", "dat", - "m1v", "m2v", "m4v", "mkv", "mpe", "yop", "vqa", "xmv", - "mve", "wtv", "webm", "vivo", "vc1", "seq", "thp", "san", - "mjpg", "smk", "vmd", "sol", "cpk", "sdp", "sbg", "rtsp", - "rpl", "rl2", "r3d", "mlp", "mjpeg", "hevc", "h265", "265", - "h264", "h263", "h261", "drc", "avs", "pva", "pmp", "ogg", - "nut", "nuv", "nsv", "mxf", "mtv", "mvi", "mxg", "lxf", - "lvf", "ivf", "mve", "cin", "hnm", "gxf", "fli", "flc", - "flx", "ffm", "wve", "uv2", "dxa", "dv", "cdxl", "cdg", - "bfi", "jv", "bik", "vid", "vb", "son", "avs", "paf", "mm", - "flm", "tmv", "4xm"); //NON-NLS private static final TreeSet SUPPORTED_IMAGE_MIME_TYPES; - private static final List SUPPORTED_VIDEO_MIME_TYPES - = Arrays.asList("application/x-shockwave-flash", "video/x-m4v", "video/quicktime", "video/avi", "video/msvideo", "video/x-msvideo", - "video/mp4", "video/x-ms-wmv", "video/mpeg", "video/asf"); //NON-NLS + private static final List CONDITIONAL_MIME_TYPES = Arrays.asList("audio/x-aiff", "application/octet-stream"); + private static final boolean openCVLoaded; static { @@ -128,9 +112,6 @@ public class ImageUtils { openCVLoaded = openCVLoadedTemp; SUPPORTED_IMAGE_EXTENSIONS = Arrays.asList(ImageIO.getReaderFileSuffixes()); - SUPPORTED_EXTENSIONS.addAll(SUPPORTED_IMAGE_EXTENSIONS); - SUPPORTED_EXTENSIONS.addAll(SUPPORTED_VIDEO_EXTENSIONS); - SUPPORTED_IMAGE_MIME_TYPES = new TreeSet<>(Arrays.asList(ImageIO.getReaderMIMETypes())); /* special cases and variants that we support, but don't get registered * with ImageIO automatically */ @@ -139,21 +120,9 @@ public class ImageUtils { "image/x-ms-bmp", "application/x-123")); SUPPORTED_IMAGE_MIME_TYPES.removeIf("application/octet-stream"::equals); - SUPPORTED_MIME_TYPES.addAll(SUPPORTED_IMAGE_MIME_TYPES); - SUPPORTED_MIME_TYPES.addAll(SUPPORTED_VIDEO_MIME_TYPES); - - //this is rarely usefull - SUPPORTED_MIME_TYPES.removeIf("application/octet-stream"::equals); } - /** - * Get the default Icon, which is the icon for a file. - * - * @return - * - * - * - * /** initialized lazily */ + /** initialized lazily */ private static FileTypeDetector fileTypeDetector; /** thread that saves generated thumbnails to disk in the background */ @@ -168,26 +137,10 @@ public class ImageUtils { return Collections.unmodifiableList(SUPPORTED_IMAGE_EXTENSIONS); } - public static List getSupportedVideoExtensions() { - return SUPPORTED_VIDEO_EXTENSIONS; - } - public static SortedSet getSupportedImageMimeTypes() { return Collections.unmodifiableSortedSet(SUPPORTED_IMAGE_MIME_TYPES); } - public static List getSupportedVideoMimeTypes() { - return SUPPORTED_VIDEO_MIME_TYPES; - } - - public static List getSupportedExtensions() { - return Collections.unmodifiableList(SUPPORTED_EXTENSIONS); - } - - public static SortedSet getSupportedMimeTypes() { - return Collections.unmodifiableSortedSet(SUPPORTED_MIME_TYPES); - } - /** * Get the default thumbnail, which is the icon for a file. Used when we can * not @@ -229,32 +182,60 @@ public class ImageUtils { return false; } AbstractFile file = (AbstractFile) content; + + return VideoUtils.isVideoThumbnailSupported(file) + || isImageThumbnailSupported(file); + + } + + public static boolean isImageThumbnailSupported(AbstractFile file) { + + return isMediaThumbnailSupported(file, SUPPORTED_IMAGE_MIME_TYPES, SUPPORTED_IMAGE_EXTENSIONS, CONDITIONAL_MIME_TYPES) + || hasImageFileHeader(file); + } + + /** + * Check if a file is "supported" by checking it mimetype and extension + * + * //TODO: this should move to a better place. Should ImageUtils and + * VideoUtils both implement/extend some base interface/abstract class. That + * would be the natural place to put this. + * + * @param file + * @param supportedMimeTypes a set of mimetypes that the could have to be + * supported + * @param supportedExtension a set of extensions a file could have to be + * supported if the mime lookup fails or is + * inconclusive + * @param conditionalMimes a set of mimetypes that a file could have to be + * supoprted if it also has a supported extension + * + * @return true if a thumbnail can be generated for the given file with the + * given lists of supported mimetype and extensions + */ + static boolean isMediaThumbnailSupported(AbstractFile file, final SortedSet supportedMimeTypes, final List supportedExtension, List conditionalMimes) { + if (file.getSize() == 0) { + return false; + } final String extension = file.getNameExtension(); try { String mimeType = getFileTypeDetector().getFileType(file); if (Objects.nonNull(mimeType)) { - return SUPPORTED_MIME_TYPES.contains(mimeType) - || (mimeType.equalsIgnoreCase("audio/x-aiff") && "iff".equalsIgnoreCase(file.getNameExtension())) - || (mimeType.equalsIgnoreCase("application/octet-stream") && SUPPORTED_EXTENSIONS.contains(extension)); + return supportedMimeTypes.contains(mimeType) + || (conditionalMimes.contains(mimeType.toLowerCase()) && supportedExtension.contains(extension)); } } catch (FileTypeDetector.FileTypeDetectorInitException | TskCoreException ex) { LOGGER.log(Level.WARNING, "Failed to look up mimetype for " + file.getName() + " using FileTypeDetector. Fallingback on AbstractFile.isMimeType", ex); - AbstractFile.MimeMatchEnum mimeMatch = file.isMimeType(SUPPORTED_MIME_TYPES); + AbstractFile.MimeMatchEnum mimeMatch = file.isMimeType(supportedMimeTypes); if (mimeMatch == AbstractFile.MimeMatchEnum.TRUE) { return true; } else if (mimeMatch == AbstractFile.MimeMatchEnum.FALSE) { return false; } } - // if we have an extension, check it - if (StringUtils.isNotBlank(extension) && SUPPORTED_EXTENSIONS.contains(extension)) { - return true; - } - - // if no extension or one that is not for an image, then read the content - return isJpegFileHeader(file) || isPngFileHeader(file); + return StringUtils.isNotBlank(extension) && supportedExtension.contains(extension); } /** @@ -304,22 +285,27 @@ public class ImageUtils { * problem making a thumbnail. */ public static Image getThumbnail(Content content, int iconSize) { - // If a thumbnail file is already saved locally - File cacheFile = getCachedThumbnailLocation(content.getId()); - if (cacheFile.exists()) { - try { - BufferedImage thumbnail = ImageIO.read(cacheFile); - if (isNull(thumbnail) || thumbnail.getWidth() != iconSize) { - return generateAndSaveThumbnail(content, iconSize, cacheFile); - } else { - return thumbnail; + if (content instanceof AbstractFile) { + AbstractFile file = (AbstractFile) content; + // If a thumbnail file is already saved locally + File cacheFile = getCachedThumbnailLocation(content.getId()); + if (cacheFile.exists()) { + try { + BufferedImage thumbnail = ImageIO.read(cacheFile); + if (isNull(thumbnail) || thumbnail.getWidth() != iconSize) { + return generateAndSaveThumbnail(file, iconSize, cacheFile); + } else { + return thumbnail; + } + } catch (Exception ex) { + LOGGER.log(Level.WARNING, "Error while reading image: " + content.getName(), ex); //NON-NLS + return generateAndSaveThumbnail(file, iconSize, cacheFile); } - } catch (Exception ex) { - LOGGER.log(Level.WARNING, "Error while reading image: " + content.getName(), ex); //NON-NLS - return generateAndSaveThumbnail(content, iconSize, cacheFile); + } else { + return generateAndSaveThumbnail(file, iconSize, cacheFile); } } else { - return generateAndSaveThumbnail(content, iconSize, cacheFile); + return DEFAULT_THUMBNAIL; } } @@ -459,25 +445,23 @@ public class ImageUtils { /** * Generate an icon and save it to specified location. * - * @param content File to generate icon for + * @param file File to generate icon for * @param iconSize * @param cacheFile Location to save thumbnail to * * @return Generated icon or null on error */ - private static Image generateAndSaveThumbnail(Content content, int iconSize, File cacheFile) { - AbstractFile f = (AbstractFile) content; - final String extension = f.getNameExtension(); + private static Image generateAndSaveThumbnail(AbstractFile file, int iconSize, File cacheFile) { BufferedImage thumbnail = null; try { - if (SUPPORTED_VIDEO_EXTENSIONS.contains(extension)) { + if (VideoUtils.isVideoThumbnailSupported(file)) { if (openCVLoaded) { - thumbnail = VideoUtils.generateVideoThumbnail((AbstractFile) content, iconSize); + thumbnail = VideoUtils.generateVideoThumbnail(file, iconSize); } else { return DEFAULT_THUMBNAIL; } } else { - thumbnail = generateImageThumbnail(content, iconSize); + thumbnail = generateImageThumbnail(file, iconSize); } if (thumbnail == null) { @@ -493,12 +477,12 @@ public class ImageUtils { } ImageIO.write(toSave, FORMAT, cacheFile); } catch (IllegalArgumentException | IOException ex1) { - LOGGER.log(Level.WARNING, "Could not write cache thumbnail: " + content, ex1); //NON-NLS + LOGGER.log(Level.WARNING, "Could not write cache thumbnail: " + file, ex1); //NON-NLS } }); } } catch (NullPointerException ex) { - logger.log(Level.WARNING, "Could not write cache thumbnail: " + content, ex); //NON-NLS + logger.log(Level.WARNING, "Could not write cache thumbnail: " + file, ex); //NON-NLS } return thumbnail; } diff --git a/Core/src/org/sleuthkit/autopsy/coreutils/VideoUtils.java b/Core/src/org/sleuthkit/autopsy/coreutils/VideoUtils.java index 2f5725aac1..0609fab045 100644 --- a/Core/src/org/sleuthkit/autopsy/coreutils/VideoUtils.java +++ b/Core/src/org/sleuthkit/autopsy/coreutils/VideoUtils.java @@ -22,6 +22,11 @@ import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.nio.file.Paths; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.SortedSet; +import java.util.TreeSet; import java.util.logging.Level; import org.netbeans.api.progress.ProgressHandle; import org.netbeans.api.progress.ProgressHandleFactory; @@ -29,6 +34,7 @@ import org.opencv.core.Mat; import org.opencv.highgui.VideoCapture; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.corelibs.ScalrWrapper; +import static org.sleuthkit.autopsy.coreutils.ImageUtils.isMediaThumbnailSupported; import org.sleuthkit.autopsy.datamodel.ContentUtils; import org.sleuthkit.datamodel.AbstractFile; @@ -37,6 +43,34 @@ import org.sleuthkit.datamodel.AbstractFile; */ public class VideoUtils { + private static final List SUPPORTED_VIDEO_EXTENSIONS + = Arrays.asList("mov", "m4v", "flv", "mp4", "3gp", "avi", "mpg", + "mpeg", "asf", "divx", "rm", "moov", "wmv", "vob", "dat", + "m1v", "m2v", "m4v", "mkv", "mpe", "yop", "vqa", "xmv", + "mve", "wtv", "webm", "vivo", "vc1", "seq", "thp", "san", + "mjpg", "smk", "vmd", "sol", "cpk", "sdp", "sbg", "rtsp", + "rpl", "rl2", "r3d", "mlp", "mjpeg", "hevc", "h265", "265", + "h264", "h263", "h261", "drc", "avs", "pva", "pmp", "ogg", + "nut", "nuv", "nsv", "mxf", "mtv", "mvi", "mxg", "lxf", + "lvf", "ivf", "mve", "cin", "hnm", "gxf", "fli", "flc", + "flx", "ffm", "wve", "uv2", "dxa", "dv", "cdxl", "cdg", + "bfi", "jv", "bik", "vid", "vb", "son", "avs", "paf", "mm", + "flm", "tmv", "4xm"); //NON-NLS + + private static final SortedSet SUPPORTED_VIDEO_MIME_TYPES = new TreeSet<>( + Arrays.asList("application/x-shockwave-flash", "video/x-m4v", "video/quicktime", "video/avi", "video/msvideo", "video/x-msvideo", + "video/mp4", "video/x-ms-wmv", "video/mpeg", "video/asf")); //NON-NLS + + private static final List CONDITIONAL_MIME_TYPES = Arrays.asList("application/octet-stream"); + + public static List getSupportedVideoExtensions() { + return SUPPORTED_VIDEO_EXTENSIONS; + } + + public static SortedSet getSupportedVideoMimeTypes() { + return Collections.unmodifiableSortedSet(SUPPORTED_VIDEO_MIME_TYPES); + } + private static final int THUMB_COLUMNS = 3; private static final int THUMB_ROWS = 3; private static final int CV_CAP_PROP_POS_MSEC = 0; @@ -52,6 +86,10 @@ public class VideoUtils { return Paths.get(Case.getCurrentCase().getTempDirectory(), "videos", file.getId() + "." + file.getNameExtension()).toFile(); } + public static boolean isVideoThumbnailSupported(AbstractFile file) { + return isMediaThumbnailSupported(file, SUPPORTED_VIDEO_MIME_TYPES, SUPPORTED_VIDEO_EXTENSIONS, CONDITIONAL_MIME_TYPES); + } + static BufferedImage generateVideoThumbnail(AbstractFile file, int iconSize) { java.io.File tempFile = getTempVideoFile(file); From 9fe0e26cefd5f026d31a58642215497ff07791d4 Mon Sep 17 00:00:00 2001 From: jmillman Date: Thu, 30 Jul 2015 12:51:12 -0400 Subject: [PATCH 3/5] cleanup DataContentViewerMedia.isSupported --- .../DataContentViewerMedia.java | 37 +------------------ .../corecomponents/MediaViewImagePanel.java | 19 +--------- .../corecomponents/MediaViewVideoPanel.java | 20 +++++++++- 3 files changed, 21 insertions(+), 55 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerMedia.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerMedia.java index 4f87aa8fdf..c3749660bf 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerMedia.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerMedia.java @@ -22,7 +22,6 @@ import java.awt.CardLayout; import java.awt.Component; import java.awt.Dimension; import java.util.List; -import static java.util.Objects.nonNull; import java.util.SortedSet; import java.util.TreeSet; import java.util.logging.Level; @@ -32,10 +31,7 @@ import org.openide.util.lookup.ServiceProvider; import org.openide.util.lookup.ServiceProviders; import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer; import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.modules.filetypeid.FileTypeDetector; import org.sleuthkit.datamodel.AbstractFile; -import org.sleuthkit.datamodel.AbstractFile.MimeMatchEnum; -import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskData.TSK_FS_NAME_FLAG_ENUM; /** @@ -52,11 +48,8 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo private final MediaViewVideoPanel videoPanel; private final boolean videoPanelInited; private final SortedSet videoExtensions; // get them from the panel - private final SortedSet videoMimes; private final MediaViewImagePanel imagePanel; private final boolean imagePanelInited; - private final SortedSet imageExtensions; // get them from the panel - private final SortedSet imageMimes; private static final String IMAGE_VIEWER_LAYER = "IMAGE"; //NON-NLS private static final String VIDEO_VIEWER_LAYER = "VIDEO"; //NON-NLS @@ -72,12 +65,9 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo videoPanel = MediaViewVideoPanel.createVideoPanel(); videoPanelInited = videoPanel.isInited(); videoExtensions = new TreeSet<>(videoPanel.getExtensionsList()); - videoMimes = new TreeSet<>(videoPanel.getMimeTypes()); imagePanel = new MediaViewImagePanel(); imagePanelInited = imagePanel.isInited(); - imageExtensions = new TreeSet<>(imagePanel.getExtensionsList()); - imageMimes = new TreeSet<>(imagePanel.getMimeTypes()); customizeComponents(); logger.log(Level.INFO, "Created MediaView instance: {0}", this); //NON-NLS @@ -239,10 +229,9 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo if (file == null) { return 0; } - String extension = file.getNameExtension(); boolean deleted = file.isDirNameFlagSet(TSK_FS_NAME_FLAG_ENUM.UNALLOC); - if (videoExtensions.contains("." + extension) && deleted) { + if (videoPanel.isSupported(file) && deleted) { return 0; } else { return 7; @@ -263,28 +252,6 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo */ List getExtensionsList(); - default boolean isSupported(AbstractFile file) { - SortedSet mimeTypes = new TreeSet<>(getMimeTypes()); - try { - String mimeType = new FileTypeDetector().getFileType(file); - if (nonNull(mimeType)) { - return mimeTypes.contains(mimeType); - } - } catch (FileTypeDetector.FileTypeDetectorInitException | TskCoreException ex) { - logger.log(Level.WARNING, "Failed to look up mimetype for " + file.getName() + " using FileTypeDetector. Fallingback on AbstractFile.isMimeType", ex); - if (!mimeTypes.isEmpty() && file.isMimeType(mimeTypes) == MimeMatchEnum.TRUE) { - return true; - } - } - - String extension = file.getNameExtension(); - - if (getExtensionsList().contains("." + extension)) { - return true; - } - - return false; - } - + boolean isSupported(AbstractFile file); } } diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/MediaViewImagePanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/MediaViewImagePanel.java index 1e7e21e35b..64a46fd86e 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/MediaViewImagePanel.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/MediaViewImagePanel.java @@ -47,10 +47,8 @@ import org.sleuthkit.autopsy.coreutils.ImageUtils; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; import org.sleuthkit.autopsy.coreutils.ThreadConfined; -import org.sleuthkit.autopsy.modules.filetypeid.FileTypeDetector; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.ReadContentInputStream; -import org.sleuthkit.datamodel.TskCoreException; /** * Image viewer part of the Media View layered pane. Uses JavaFX to display the @@ -222,22 +220,7 @@ public class MediaViewImagePanel extends JPanel implements DataContentViewerMedi @Override public boolean isSupported(AbstractFile file) { - if (DataContentViewerMedia.MediaViewPanel.super.isSupported(file)) { - return true; - } else { - String extension = file.getNameExtension(); - try { - String mimeType = new FileTypeDetector().getFileType(file); - - return (mimeType.equalsIgnoreCase("audio/x-aiff") && "iff".equalsIgnoreCase(extension)) - || (mimeType.equalsIgnoreCase("application/octet-stream") && getExtensionsList().contains(extension)); - - } catch (FileTypeDetector.FileTypeDetectorInitException | TskCoreException ex) { - LOGGER.log(Level.WARNING, "Failed to get mime type for file", ex); - } - - return ImageUtils.thumbnailSupported(file); - } + return ImageUtils.isImageThumbnailSupported(file); } /** diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/MediaViewVideoPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/MediaViewVideoPanel.java index 2d41d27a27..7702b9e9ad 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/MediaViewVideoPanel.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/MediaViewVideoPanel.java @@ -21,12 +21,16 @@ package org.sleuthkit.autopsy.corecomponents; import java.awt.Dimension; import java.util.Arrays; import java.util.List; +import static java.util.Objects.nonNull; import java.util.Set; +import java.util.SortedSet; import java.util.TreeSet; import java.util.logging.Level; import javax.swing.JPanel; import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.modules.filetypeid.FileTypeDetector; import org.sleuthkit.datamodel.AbstractFile; +import org.sleuthkit.datamodel.TskCoreException; /** * Video viewer part of the Media View layered pane. @@ -132,9 +136,21 @@ public abstract class MediaViewVideoPanel extends JPanel implements FrameCapture String extension = file.getNameExtension(); //TODO: is this what we want, to require both extension and mimetype support? if (AUDIO_EXTENSIONS.contains("." + extension) || getExtensionsList().contains("." + extension)) { - return DataContentViewerMedia.MediaViewPanel.super.isSupported(file); //To change body of generated methods, choose Tools | Templates. + SortedSet mimeTypes = new TreeSet<>(getMimeTypes()); + try { + String mimeType = new FileTypeDetector().getFileType(file); + if (nonNull(mimeType)) { + return mimeTypes.contains(mimeType); + } + } catch (FileTypeDetector.FileTypeDetectorInitException | TskCoreException ex) { + logger.log(Level.WARNING, "Failed to look up mimetype for " + file.getName() + " using FileTypeDetector. Fallingback on AbstractFile.isMimeType", ex); + if (!mimeTypes.isEmpty() && file.isMimeType(mimeTypes) == AbstractFile.MimeMatchEnum.TRUE) { + return true; + } + } + + return getExtensionsList().contains("." + extension); } return false; } - } From c74f20480817788adf3d80c0ebe951e28469b11a Mon Sep 17 00:00:00 2001 From: jmillman Date: Thu, 30 Jul 2015 13:01:17 -0400 Subject: [PATCH 4/5] fix potential NPE --- Core/src/org/sleuthkit/autopsy/coreutils/VideoUtils.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/coreutils/VideoUtils.java b/Core/src/org/sleuthkit/autopsy/coreutils/VideoUtils.java index 0609fab045..40569e8ec0 100644 --- a/Core/src/org/sleuthkit/autopsy/coreutils/VideoUtils.java +++ b/Core/src/org/sleuthkit/autopsy/coreutils/VideoUtils.java @@ -131,11 +131,11 @@ public class VideoUtils { for (int x = 0; x < THUMB_COLUMNS; x++) { for (int y = 0; y < THUMB_ROWS; y++) { if (!videoFile.set(CV_CAP_PROP_POS_MSEC, timestamp + x * framkeskip + y * framkeskip * THUMB_COLUMNS)) { - break; + break; // if we can't set the time, return black for that frame } //read the frame into the image/matrix if (!videoFile.read(imageMatrix)) { - break; //if the image for some reason is bad, return default icon + break; //if the image for some reason is bad, return black for that frame } if (bufferedImage == null) { @@ -160,6 +160,6 @@ public class VideoUtils { videoFile.release(); // close the file - return ScalrWrapper.resizeFast(bufferedImage, iconSize); + return bufferedImage == null ? bufferedImage : ScalrWrapper.resizeFast(bufferedImage, iconSize); } } From 4f04fa641aa886f95d604bf8d65c6ba141d61bb1 Mon Sep 17 00:00:00 2001 From: jmillman Date: Thu, 30 Jul 2015 13:19:58 -0400 Subject: [PATCH 5/5] add mimetypes that are supported but seam to be missing from the ones reported. --- Core/src/org/sleuthkit/autopsy/coreutils/ImageUtils.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/coreutils/ImageUtils.java b/Core/src/org/sleuthkit/autopsy/coreutils/ImageUtils.java index 7e6fc57304..0e05ee0001 100755 --- a/Core/src/org/sleuthkit/autopsy/coreutils/ImageUtils.java +++ b/Core/src/org/sleuthkit/autopsy/coreutils/ImageUtils.java @@ -118,6 +118,8 @@ public class ImageUtils { SUPPORTED_IMAGE_MIME_TYPES.addAll(Arrays.asList( "image/x-rgb", "image/x-ms-bmp", + "image/x-portable-graymap", + "image/x-portable-bitmap", "application/x-123")); SUPPORTED_IMAGE_MIME_TYPES.removeIf("application/octet-stream"::equals); }