mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-13 08:26:15 +00:00
check for interupts/cancelation in ImageUtils methods/tasks; set cancelation text on progress bars.
This commit is contained in:
parent
0d8855d8b4
commit
4938ad4487
@ -32,10 +32,10 @@ import java.util.concurrent.CancellationException;
|
|||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.Future;
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import javax.swing.SortOrder;
|
import javax.swing.SortOrder;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.SwingWorker;
|
import javax.swing.SwingWorker;
|
||||||
import javax.swing.Timer;
|
import javax.swing.Timer;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
@ -213,13 +213,11 @@ class ThumbnailViewChildren extends Children.Keys<Integer> {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Node that wraps around original node and adds the bitmap icon
|
* Node that wraps around original node and adds the bitmap icon
|
||||||
* representing the picture
|
* representing the picture
|
||||||
*/
|
*/
|
||||||
private class ThumbnailViewNode extends FilterNode {
|
class ThumbnailViewNode extends FilterNode {
|
||||||
|
|
||||||
private Logger logger = Logger.getLogger(ThumbnailViewNode.class.getName());
|
private Logger logger = Logger.getLogger(ThumbnailViewNode.class.getName());
|
||||||
|
|
||||||
@ -282,19 +280,28 @@ class ThumbnailViewChildren extends Children.Keys<Integer> {
|
|||||||
|
|
||||||
private final Content content;
|
private final Content content;
|
||||||
private final ProgressHandle progressHandle;
|
private final ProgressHandle progressHandle;
|
||||||
|
private volatile boolean started = false;
|
||||||
|
private final String progressText;
|
||||||
|
|
||||||
ThumbnailLoadTask(Content content) {
|
ThumbnailLoadTask(Content content) {
|
||||||
this.content = content;
|
this.content = content;
|
||||||
final String progressText = Bundle.ThumbnailViewNode_progressHandle_text(content.getName());
|
progressText = Bundle.ThumbnailViewNode_progressHandle_text(content.getName());
|
||||||
progressHandle = ProgressHandle.createHandle(progressText);
|
progressHandle = ProgressHandle.createHandle(progressText);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Image doInBackground() throws Exception {
|
protected Image doInBackground() throws Exception {
|
||||||
progressHandle.start();
|
synchronized (progressHandle) {
|
||||||
|
progressHandle.start();
|
||||||
|
started = true;
|
||||||
|
}
|
||||||
return ImageUtils.getThumbnail(content, iconSize);
|
return ImageUtils.getThumbnail(content, iconSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void cancel() {
|
||||||
|
SwingUtilities.invokeLater(() -> progressHandle.setDisplayName(progressText + " (Cancelling)"));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void done() {
|
protected void done() {
|
||||||
super.done();
|
super.done();
|
||||||
@ -302,11 +309,18 @@ class ThumbnailViewChildren extends Children.Keys<Integer> {
|
|||||||
thumbCache = new SoftReference<>(super.get());
|
thumbCache = new SoftReference<>(super.get());
|
||||||
fireIconChange();
|
fireIconChange();
|
||||||
} catch (CancellationException ex) {
|
} catch (CancellationException ex) {
|
||||||
//do nothing, it was cancelled
|
//Task was cancelled, do nothing
|
||||||
} catch (InterruptedException | ExecutionException ex) {
|
} catch (InterruptedException | ExecutionException ex) {
|
||||||
logger.log(Level.SEVERE, "Error getting thumbnail icon for " + content.getName(), ex); //NON-NLS
|
if (ex.getCause() instanceof CancellationException) {
|
||||||
|
} else {
|
||||||
|
logger.log(Level.SEVERE, "Error getting thumbnail icon for " + content.getName(), ex); //NON-NLS
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
progressHandle.finish();
|
synchronized (progressHandle) {
|
||||||
|
if (started) {
|
||||||
|
progressHandle.finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
if (timer != null) {
|
if (timer != null) {
|
||||||
timer.stop();
|
timer.stop();
|
||||||
timer = null;
|
timer = null;
|
||||||
@ -314,24 +328,30 @@ class ThumbnailViewChildren extends Children.Keys<Integer> {
|
|||||||
thumbTask = null;
|
thumbTask = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final ExecutorService executor = Executors.newFixedThreadPool(4,
|
private final ExecutorService executor = Executors.newFixedThreadPool(4,
|
||||||
new ThreadFactoryBuilder().setNameFormat("Thumbnail-Loader-%d").build());
|
new ThreadFactoryBuilder().setNameFormat("Thumbnail-Loader-%d").build());
|
||||||
|
|
||||||
private final List<Future<?>> futures = new ArrayList<>();
|
private final List<ThumbnailViewNode.ThumbnailLoadTask> tasks = new ArrayList<>();
|
||||||
|
|
||||||
synchronized void cancelLoadingThumbnails() {
|
synchronized void cancelLoadingThumbnails() {
|
||||||
futures.forEach(future -> future.cancel(true));
|
tasks.forEach(ThumbnailViewNode.ThumbnailLoadTask::cancel);
|
||||||
futures.clear();
|
tasks.clear();
|
||||||
|
executor.shutdownNow();
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized ThumbnailViewNode.ThumbnailLoadTask loadThumbnail(ThumbnailViewNode node, Content content) {
|
private synchronized ThumbnailViewNode.ThumbnailLoadTask loadThumbnail(ThumbnailViewNode node, Content content) {
|
||||||
ThumbnailViewNode.ThumbnailLoadTask task = node.new ThumbnailLoadTask(content);
|
if (executor.isShutdown() == false) {
|
||||||
futures.add(task);
|
ThumbnailViewNode.ThumbnailLoadTask task = node.new ThumbnailLoadTask(content);
|
||||||
executor.submit(task);
|
tasks.add(task);
|
||||||
return task;
|
executor.submit(task);
|
||||||
|
return task;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -40,6 +40,7 @@ import java.util.List;
|
|||||||
import static java.util.Objects.nonNull;
|
import static java.util.Objects.nonNull;
|
||||||
import java.util.SortedSet;
|
import java.util.SortedSet;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
|
import java.util.concurrent.CancellationException;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
@ -164,8 +165,8 @@ public class ImageUtils {
|
|||||||
/**
|
/**
|
||||||
* 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
|
private static final Executor imageSaver =
|
||||||
= Executors.newSingleThreadExecutor(new BasicThreadFactory.Builder()
|
Executors.newSingleThreadExecutor(new BasicThreadFactory.Builder()
|
||||||
.namingPattern("thumbnail-saver-%d").build()); //NON-NLS
|
.namingPattern("thumbnail-saver-%d").build()); //NON-NLS
|
||||||
|
|
||||||
public static List<String> getSupportedImageExtensions() {
|
public static List<String> getSupportedImageExtensions() {
|
||||||
@ -213,7 +214,7 @@ public class ImageUtils {
|
|||||||
* @param file the AbstractFile to test
|
* @param file the AbstractFile to test
|
||||||
*
|
*
|
||||||
* @return true if the file is an image we can read and generate thumbnail
|
* @return true if the file is an image we can read and generate thumbnail
|
||||||
* for.
|
* for.
|
||||||
*/
|
*/
|
||||||
public static boolean isImageThumbnailSupported(AbstractFile file) {
|
public static boolean isImageThumbnailSupported(AbstractFile file) {
|
||||||
return isMediaThumbnailSupported(file, "image/", SUPPORTED_IMAGE_MIME_TYPES, SUPPORTED_IMAGE_EXTENSIONS) || hasImageFileHeader(file);//NON-NLS
|
return isMediaThumbnailSupported(file, "image/", SUPPORTED_IMAGE_MIME_TYPES, SUPPORTED_IMAGE_EXTENSIONS) || hasImageFileHeader(file);//NON-NLS
|
||||||
@ -239,16 +240,17 @@ public class ImageUtils {
|
|||||||
* VideoUtils both implement/extend some base interface/abstract class. That
|
* VideoUtils both implement/extend some base interface/abstract class. That
|
||||||
* would be the natural place to put this.
|
* would be the natural place to put this.
|
||||||
*
|
*
|
||||||
* @param file the AbstractFile to test
|
* @param file the AbstractFile to test
|
||||||
* @param mimeTypePrefix a MIME 'top-level type name' such as "image/",
|
* @param mimeTypePrefix a MIME 'top-level type name' such as "image/",
|
||||||
* including the "/". In addition to the list of supported MIME types, any
|
* including the "/". In addition to the list of
|
||||||
* type that starts with this prefix will be regarded as supported
|
* supported MIME types, any type that starts with
|
||||||
|
* this prefix will be regarded as supported
|
||||||
* @param supportedMimeTypes a collection of mimetypes that are supported
|
* @param supportedMimeTypes a collection of mimetypes that are supported
|
||||||
* @param supportedExtension a collection of extensions that are supported
|
* @param supportedExtension a collection of extensions that are supported
|
||||||
*
|
*
|
||||||
* @return true if a thumbnail can be generated for the given file based on
|
* @return true if a thumbnail can be generated for the given file based on
|
||||||
* the given MIME type prefix and lists of supported MIME types and
|
* the given MIME type prefix and lists of supported MIME types and
|
||||||
* extensions
|
* extensions
|
||||||
*/
|
*/
|
||||||
static boolean isMediaThumbnailSupported(AbstractFile file, String mimeTypePrefix, final Collection<String> supportedMimeTypes, final List<String> supportedExtension) {
|
static boolean isMediaThumbnailSupported(AbstractFile file, String mimeTypePrefix, final Collection<String> supportedMimeTypes, final List<String> supportedExtension) {
|
||||||
if (false == file.isFile() || file.getSize() <= 0) {
|
if (false == file.isFile() || file.getSize() <= 0) {
|
||||||
@ -282,7 +284,7 @@ public class ImageUtils {
|
|||||||
* @return a FileTypeDetector
|
* @return a FileTypeDetector
|
||||||
*
|
*
|
||||||
* @throws FileTypeDetectorInitException if initializing the
|
* @throws FileTypeDetectorInitException if initializing the
|
||||||
* FileTypeDetector failed.
|
* FileTypeDetector failed.
|
||||||
*/
|
*/
|
||||||
synchronized private static FileTypeDetector getFileTypeDetector() throws FileTypeDetector.FileTypeDetectorInitException {
|
synchronized private static FileTypeDetector getFileTypeDetector() throws FileTypeDetector.FileTypeDetectorInitException {
|
||||||
if (fileTypeDetector == null) {
|
if (fileTypeDetector == null) {
|
||||||
@ -295,11 +297,11 @@ public class ImageUtils {
|
|||||||
* Get a thumbnail of a specified size for the given image. Generates the
|
* Get a thumbnail of a specified size for the given image. Generates the
|
||||||
* thumbnail if it is not already cached.
|
* thumbnail if it is not already cached.
|
||||||
*
|
*
|
||||||
* @param content the content to generate a thumbnail for
|
* @param content the content to generate a thumbnail for
|
||||||
* @param iconSize the size (one side of a square) in pixels to generate
|
* @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.
|
* problem making a thumbnail.
|
||||||
*/
|
*/
|
||||||
public static BufferedImage getThumbnail(Content content, int iconSize) {
|
public static BufferedImage getThumbnail(Content content, int iconSize) {
|
||||||
if (content instanceof AbstractFile) {
|
if (content instanceof AbstractFile) {
|
||||||
@ -310,8 +312,14 @@ public class ImageUtils {
|
|||||||
* to rescale easily, but we lose animations.
|
* to rescale easily, but we lose animations.
|
||||||
*/
|
*/
|
||||||
try (BufferedInputStream bufferedReadContentStream = getBufferedReadContentStream(file);) {
|
try (BufferedInputStream bufferedReadContentStream = getBufferedReadContentStream(file);) {
|
||||||
|
if (Thread.interrupted()) {
|
||||||
|
return DEFAULT_THUMBNAIL;
|
||||||
|
}
|
||||||
final BufferedImage image = ImageIO.read(bufferedReadContentStream);
|
final BufferedImage image = ImageIO.read(bufferedReadContentStream);
|
||||||
if (image != null) {
|
if (image != null) {
|
||||||
|
if (Thread.interrupted()) {
|
||||||
|
return DEFAULT_THUMBNAIL;
|
||||||
|
}
|
||||||
return ScalrWrapper.resizeHighQuality(image, iconSize, iconSize);
|
return ScalrWrapper.resizeHighQuality(image, iconSize, iconSize);
|
||||||
}
|
}
|
||||||
} catch (IOException iOException) {
|
} catch (IOException iOException) {
|
||||||
@ -321,6 +329,9 @@ public class ImageUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Task<javafx.scene.image.Image> thumbnailTask = newGetThumbnailTask(file, iconSize, true);
|
Task<javafx.scene.image.Image> thumbnailTask = newGetThumbnailTask(file, iconSize, true);
|
||||||
|
if (Thread.interrupted()) {
|
||||||
|
return DEFAULT_THUMBNAIL;
|
||||||
|
}
|
||||||
thumbnailTask.run();
|
thumbnailTask.run();
|
||||||
try {
|
try {
|
||||||
return SwingFXUtils.fromFXImage(thumbnailTask.get(), null);
|
return SwingFXUtils.fromFXImage(thumbnailTask.get(), null);
|
||||||
@ -338,7 +349,7 @@ public class ImageUtils {
|
|||||||
* @param file The AbstractFile to get a stream for.
|
* @param file The AbstractFile to get a stream for.
|
||||||
*
|
*
|
||||||
* @return A BufferedInputStream wrapped around a ReadContentStream for the
|
* @return A BufferedInputStream wrapped around a ReadContentStream for the
|
||||||
* given AbstractFile
|
* given AbstractFile
|
||||||
*/
|
*/
|
||||||
private static BufferedInputStream getBufferedReadContentStream(AbstractFile file) {
|
private static BufferedInputStream getBufferedReadContentStream(AbstractFile file) {
|
||||||
return new BufferedInputStream(new ReadContentInputStream(file));
|
return new BufferedInputStream(new ReadContentInputStream(file));
|
||||||
@ -348,11 +359,11 @@ public class ImageUtils {
|
|||||||
* Get a thumbnail of a specified size for the given image. Generates the
|
* Get a thumbnail of a specified size for the given image. Generates the
|
||||||
* thumbnail if it is not already cached.
|
* thumbnail if it is not already cached.
|
||||||
*
|
*
|
||||||
* @param content the content to generate a thumbnail for
|
* @param content the content to generate a thumbnail for
|
||||||
* @param iconSize the size (one side of a square) in pixels to generate
|
* @param iconSize the size (one side of a square) in pixels to generate
|
||||||
*
|
*
|
||||||
* @return File object for cached image. Is guaranteed to exist, as long as
|
* @return File object for cached image. Is guaranteed to exist, as long as
|
||||||
* there was not an error generating or saving the thumbnail.
|
* there was not an error generating or saving the thumbnail.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public static File getCachedThumbnailFile(Content content, int iconSize) {
|
public static File getCachedThumbnailFile(Content content, int iconSize) {
|
||||||
@ -367,8 +378,8 @@ public class ImageUtils {
|
|||||||
* @param fileID the fileID to get the cached thumbnail location for
|
* @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
|
* This file may not actually exist(yet). Returns null if there was
|
||||||
* problem getting the file, such as no case was open.
|
* any problem getting the file, such as no case was open.
|
||||||
*/
|
*/
|
||||||
private static File getCachedThumbnailLocation(long fileID) {
|
private static File getCachedThumbnailLocation(long fileID) {
|
||||||
return cacheFileMap.computeIfAbsent(fileID, id -> {
|
return cacheFileMap.computeIfAbsent(fileID, id -> {
|
||||||
@ -426,7 +437,7 @@ public class ImageUtils {
|
|||||||
* @param file the AbstractFile to parse
|
* @param file the AbstractFile to parse
|
||||||
*
|
*
|
||||||
* @return Offset of first Start Of Image marker, or 0 if none found. This
|
* @return Offset of first Start Of Image marker, or 0 if none found. This
|
||||||
* will let ImageIO try to open it from offset 0.
|
* will let ImageIO try to open it from offset 0.
|
||||||
*/
|
*/
|
||||||
private static long getJfifStartOfImageOffset(AbstractFile file) {
|
private static long getJfifStartOfImageOffset(AbstractFile file) {
|
||||||
byte[] fileHeaderBuffer;
|
byte[] fileHeaderBuffer;
|
||||||
@ -506,7 +517,7 @@ public class ImageUtils {
|
|||||||
* @return the width in pixels
|
* @return the width in pixels
|
||||||
*
|
*
|
||||||
* @throws IOException If the file is not a supported image or the width
|
* @throws IOException If the file is not a supported image or the width
|
||||||
* could not be determined.
|
* could not be determined.
|
||||||
*/
|
*/
|
||||||
static public int getImageWidth(AbstractFile file) throws IOException {
|
static public int getImageWidth(AbstractFile file) throws IOException {
|
||||||
return getImageProperty(file,
|
return getImageProperty(file,
|
||||||
@ -523,7 +534,7 @@ public class ImageUtils {
|
|||||||
* @return the height in pixels
|
* @return the height in pixels
|
||||||
*
|
*
|
||||||
* @throws IOException If the file is not a supported image or the height
|
* @throws IOException If the file is not a supported image or the height
|
||||||
* could not be determined.
|
* could not be determined.
|
||||||
*/
|
*/
|
||||||
static public int getImageHeight(AbstractFile file) throws IOException {
|
static public int getImageHeight(AbstractFile file) throws IOException {
|
||||||
return getImageProperty(file,
|
return getImageProperty(file,
|
||||||
@ -552,17 +563,18 @@ public class ImageUtils {
|
|||||||
* public methods that pull particular (usually meta-)data out of a image
|
* public methods that pull particular (usually meta-)data out of a image
|
||||||
* file.
|
* file.
|
||||||
*
|
*
|
||||||
* @param file the file to extract the data from
|
* @param file the file to extract the data from
|
||||||
* @param errorTemplate a message template used to log errors. Should take
|
* @param errorTemplate a message template used to log errors. Should
|
||||||
* one parameter: the file's unique path or name.
|
* take one parameter: the file's unique path or
|
||||||
|
* name.
|
||||||
* @param propertyExtractor an implementation of {@link PropertyExtractor}
|
* @param propertyExtractor an implementation of {@link PropertyExtractor}
|
||||||
* used to retrieve the specific property.
|
* used to retrieve the specific property.
|
||||||
*
|
*
|
||||||
* @return the the value of the property extracted by the given
|
* @return the the value of the property extracted by the given
|
||||||
* propertyExtractor
|
* propertyExtractor
|
||||||
*
|
*
|
||||||
* @throws IOException if there was a problem reading the property from the
|
* @throws IOException if there was a problem reading the property from the
|
||||||
* file.
|
* file.
|
||||||
*
|
*
|
||||||
* @see PropertyExtractor
|
* @see PropertyExtractor
|
||||||
* @see #getImageHeight(org.sleuthkit.datamodel.AbstractFile)
|
* @see #getImageHeight(org.sleuthkit.datamodel.AbstractFile)
|
||||||
@ -606,8 +618,8 @@ public class ImageUtils {
|
|||||||
* but is not started automatically. Clients are responsible for running the
|
* but is not started automatically. Clients are responsible for running the
|
||||||
* task, monitoring its progress, and using its result.
|
* task, monitoring its progress, and using its result.
|
||||||
*
|
*
|
||||||
* @param file The file to create a thumbnail for.
|
* @param file The file to create a thumbnail for.
|
||||||
* @param iconSize The size of the thumbnail.
|
* @param iconSize The size of the thumbnail.
|
||||||
* @param defaultOnFailure Whether or not to default on failure.
|
* @param defaultOnFailure Whether or not to default on failure.
|
||||||
*
|
*
|
||||||
* @return a new Task that returns a thumbnail as its result.
|
* @return a new Task that returns a thumbnail as its result.
|
||||||
@ -695,7 +707,9 @@ public class ImageUtils {
|
|||||||
throw new IIOException(msg);
|
throw new IIOException(msg);
|
||||||
}
|
}
|
||||||
updateProgress(-1, 1);
|
updateProgress(-1, 1);
|
||||||
|
if (isCancelled()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
//resize, or if that fails, crop it
|
//resize, or if that fails, crop it
|
||||||
try {
|
try {
|
||||||
thumbnail = ScalrWrapper.resizeFast(bufferedImage, iconSize);
|
thumbnail = ScalrWrapper.resizeFast(bufferedImage, iconSize);
|
||||||
@ -709,6 +723,9 @@ public class ImageUtils {
|
|||||||
final int cropHeight = Math.min(iconSize, height);
|
final int cropHeight = Math.min(iconSize, height);
|
||||||
final int cropWidth = Math.min(iconSize, width);
|
final int cropWidth = Math.min(iconSize, width);
|
||||||
try {
|
try {
|
||||||
|
if (isCancelled()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
thumbnail = ScalrWrapper.cropImage(bufferedImage, cropWidth, cropHeight);
|
thumbnail = ScalrWrapper.cropImage(bufferedImage, cropWidth, cropHeight);
|
||||||
} catch (Exception cropException) {
|
} catch (Exception cropException) {
|
||||||
LOGGER.log(Level.WARNING, "Could not crop {0}: " + cropException.toString(), ImageUtils.getContentPathSafe(file)); //NON-NLS
|
LOGGER.log(Level.WARNING, "Could not crop {0}: " + cropException.toString(), ImageUtils.getContentPathSafe(file)); //NON-NLS
|
||||||
@ -720,17 +737,15 @@ public class ImageUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isCancelled()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
updateProgress(-1, 1);
|
updateProgress(-1, 1);
|
||||||
|
|
||||||
//if we got a valid thumbnail save it
|
//if we got a valid thumbnail save it
|
||||||
if ((cacheFile != null) && thumbnail != null && DEFAULT_THUMBNAIL != thumbnail) {
|
if ((cacheFile != null) && thumbnail != null && DEFAULT_THUMBNAIL != thumbnail) {
|
||||||
saveThumbnail(thumbnail);
|
saveThumbnail(thumbnail);
|
||||||
}
|
}
|
||||||
|
if (isCancelled()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
return SwingFXUtils.toFXImage(thumbnail, null);
|
return SwingFXUtils.toFXImage(thumbnail, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -806,6 +821,9 @@ public class ImageUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected javafx.scene.image.Image readImage() throws IOException {
|
protected javafx.scene.image.Image readImage() throws IOException {
|
||||||
|
if (isCancelled()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
if (ImageUtils.isGIF(file)) {
|
if (ImageUtils.isGIF(file)) {
|
||||||
//use JavaFX to directly read GIF to preserve potential animation
|
//use JavaFX to directly read GIF to preserve potential animation
|
||||||
javafx.scene.image.Image image = new javafx.scene.image.Image(getBufferedReadContentStream(file));
|
javafx.scene.image.Image image = new javafx.scene.image.Image(getBufferedReadContentStream(file));
|
||||||
@ -865,6 +883,14 @@ public class ImageUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCancelled() {
|
||||||
|
if (Thread.interrupted()) {
|
||||||
|
this.cancel(true);
|
||||||
|
}
|
||||||
|
return super.isCancelled();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void succeeded() {
|
protected void succeeded() {
|
||||||
super.succeeded();
|
super.succeeded();
|
||||||
@ -976,7 +1002,7 @@ public class ImageUtils {
|
|||||||
* @param iconSize
|
* @param iconSize
|
||||||
*
|
*
|
||||||
* @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.
|
* problem making a thumbnail.
|
||||||
*
|
*
|
||||||
* @deprecated use getThumbnail(org.sleuthkit.datamodel.Content, int)
|
* @deprecated use getThumbnail(org.sleuthkit.datamodel.Content, int)
|
||||||
* instead.
|
* instead.
|
||||||
@ -995,7 +1021,7 @@ public class ImageUtils {
|
|||||||
* @param iconSize
|
* @param iconSize
|
||||||
*
|
*
|
||||||
* @return File object for cached image. Is guaranteed to exist, as long as
|
* @return File object for cached image. Is guaranteed to exist, as long as
|
||||||
* there was not an error generating or saving the thumbnail.
|
* there was not an error generating or saving the thumbnail.
|
||||||
*
|
*
|
||||||
* @deprecated use getCachedThumbnailFile(org.sleuthkit.datamodel.Content,
|
* @deprecated use getCachedThumbnailFile(org.sleuthkit.datamodel.Content,
|
||||||
* int) instead.
|
* int) instead.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user