move isGIF to autopsy Core ImageUtils, use it to load GIFs in Media tab (preserves animation)

This commit is contained in:
jmillman 2015-12-11 17:34:30 -05:00
parent 7e2751ec7d
commit f64a48ba30
3 changed files with 46 additions and 31 deletions

View File

@ -249,6 +249,16 @@ public class MediaViewImagePanel extends JPanel implements DataContentViewerMedi
protected Image call() throws Exception {
updateMessage(Bundle.LoadImageTask_mesageText(file.getName()));
try (InputStream inputStream = new BufferedInputStream(new ReadContentInputStream(file));) {
if (ImageUtils.isGIF(file)) {
//directly read GIF to preserve potential animation,
Image image = new Image(new BufferedInputStream(inputStream));
if (image.isError() == false) {
return image;
}
//fall through to default iamge reading code if there was an error
}
ImageInputStream input = ImageIO.createImageInputStream(inputStream);
if (input == null) {
throw new IIOException("Could not create ImageInputStream."); //NOI18N

View File

@ -22,6 +22,7 @@
*/
package org.sleuthkit.autopsy.coreutils;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.io.Files;
import java.awt.Image;
import java.awt.image.BufferedImage;
@ -36,6 +37,7 @@ import java.util.Collections;
import java.util.List;
import java.util.Objects;
import static java.util.Objects.isNull;
import static java.util.Objects.nonNull;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.concurrent.Executor;
@ -76,8 +78,11 @@ public class ImageUtils {
private static final Logger logger = LOGGER;
private static final BufferedImage DEFAULT_THUMBNAIL;
private static final String IMAGE_GIF_MIME = "image/gif";
private static final SortedSet<String> GIF_MIME_SET = ImmutableSortedSet.copyOf(new String[]{IMAGE_GIF_MIME});
private static final List<String> SUPPORTED_IMAGE_EXTENSIONS;
private static final TreeSet<String> SUPPORTED_IMAGE_MIME_TYPES;
private static final SortedSet<String> SUPPORTED_IMAGE_MIME_TYPES;
private static final List<String> CONDITIONAL_MIME_TYPES = Arrays.asList("audio/x-aiff", "application/octet-stream");
private static final boolean openCVLoaded;
@ -124,7 +129,7 @@ public class ImageUtils {
"image/x-ms-bmp",
"image/x-portable-graymap",
"image/x-portable-bitmap",
"application/x-123"));
"application/x-123")); //TODO: is this correct? -jm
SUPPORTED_IMAGE_MIME_TYPES.removeIf("application/octet-stream"::equals);
}
@ -200,6 +205,30 @@ public class ImageUtils {
|| hasImageFileHeader(file);
}
public static boolean isGIF(AbstractFile file) {
try {
final FileTypeDetector fileTypeDetector = getFileTypeDetector();
if (nonNull(fileTypeDetector)) {
String fileType = fileTypeDetector.getFileType(file);
return IMAGE_GIF_MIME.equalsIgnoreCase(fileType);
}
} catch (TskCoreException | FileTypeDetectorInitException ex) {
LOGGER.log(Level.WARNING, "Failed to get mime type with FileTypeDetector.", ex);
}
LOGGER.log(Level.WARNING, "Falling back on direct mime type check.");
switch (file.isMimeType(GIF_MIME_SET)) {
case TRUE:
return true;
case UNDEFINED:
LOGGER.log(Level.WARNING, "Falling back on extension check.");
return "gif".equals(file.getNameExtension());
case FALSE:
default:
return false;
}
}
/**
* Check if a file is "supported" by checking it mimetype and extension
*

View File

@ -26,7 +26,6 @@ import static java.util.Objects.isNull;
import static java.util.Objects.nonNull;
import java.util.Optional;
import java.util.Set;
import java.util.TreeSet;
import java.util.logging.Level;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@ -81,10 +80,6 @@ public enum FileTypeUtils {
*/
private static FileTypeDetector FILE_TYPE_DETECTOR;
private static final String IMAGE_GIF_MIME = "image/gif";
private static final TreeSet<String> GIF_MIME_SET = new TreeSet<>(Arrays.asList(IMAGE_GIF_MIME));
/**
* static initalizer block to initialize sets of extensions and mimetypes to
* be supported
@ -161,7 +156,8 @@ public enum FileTypeUtils {
return FILE_TYPE_DETECTOR;
}
/** is the given file supported by image analyzer? ie, does it have a
/**
* is the given file supported by image analyzer? ie, does it have a
* supported mime type (image/*, or video/*). if no mime type is found, does
* it have a supported extension or a jpeg/png header?
*
@ -181,27 +177,7 @@ public enum FileTypeUtils {
}
public static boolean isGIF(AbstractFile file) {
try {
final FileTypeDetector fileTypeDetector = getFileTypeDetector();
if (nonNull(fileTypeDetector)) {
String fileType = fileTypeDetector.getFileType(file);
return IMAGE_GIF_MIME.equalsIgnoreCase(fileType);
}
} catch (TskCoreException ex) {
LOGGER.log(Level.WARNING, "Failed to get mime type with FileTypeDetector.", ex);
}
LOGGER.log(Level.WARNING, "Falling back on direct mime type check.");
switch (file.isMimeType(GIF_MIME_SET)) {
case TRUE:
return true;
case UNDEFINED:
LOGGER.log(Level.WARNING, "Falling back on extension check.");
return "gif".equals(file.getNameExtension());
case FALSE:
default:
return false;
}
return ImageUtils.isGIF(file);
}
/**
@ -210,8 +186,8 @@ public enum FileTypeUtils {
* @param file
*
* @return an Optional containg: True if the file has an image or video mime
* type. False if a non image/video mimetype. empty Optional if
* a mimetype could not be detected.
* type. False if a non image/video mimetype. empty Optional if a
* mimetype could not be detected.
*/
static Optional<Boolean> hasDrawableMimeType(AbstractFile file) throws TskCoreException {