clean up ImageUtils logging

This commit is contained in:
jmillman 2016-02-12 16:15:37 -05:00
parent 02c4336aaf
commit b9c35b7a4f

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2012-15 Basis Technology Corp. * Copyright 2012-16 Basis Technology Corp.
* *
* Copyright 2012 42six Solutions. * Copyright 2012 42six Solutions.
* Contact: aebadirad <at> 42six <dot> com * Contact: aebadirad <at> 42six <dot> com
@ -30,6 +30,7 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.text.MessageFormat;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Iterator; import java.util.Iterator;
@ -74,10 +75,6 @@ public class ImageUtils {
private static final Logger LOGGER = Logger.getLogger(ImageUtils.class.getName()); private static final Logger LOGGER = Logger.getLogger(ImageUtils.class.getName());
private static final String COULD_NOT_WRITE_CACHE_THUMBNAIL = "Could not write cache thumbnail: "; //NOI18N NON-NLS
private static final String COULD_NOT_CREATE_IMAGE_INPUT_STREAM = "Could not create ImageInputStream."; //NOI18N NON-NLS
private static final String NO_IMAGE_READER_FOUND_FOR_ = "No ImageReader found for "; //NOI18N NON-NLS
/** /**
* save thumbnails to disk as this format * save thumbnails to disk as this format
*/ */
@ -594,7 +591,7 @@ public class ImageUtils {
try (InputStream inputStream = new BufferedInputStream(new ReadContentInputStream(file));) { try (InputStream inputStream = new BufferedInputStream(new ReadContentInputStream(file));) {
try (ImageInputStream input = ImageIO.createImageInputStream(inputStream)) { try (ImageInputStream input = ImageIO.createImageInputStream(inputStream)) {
if (input == null) { if (input == null) {
IIOException iioException = new IIOException(COULD_NOT_CREATE_IMAGE_INPUT_STREAM); IIOException iioException = new IIOException("Could not create ImageInputStream.");
LOGGER.log(Level.WARNING, errorTemplate + iioException.toString(), getContentPathSafe(file)); LOGGER.log(Level.WARNING, errorTemplate + iioException.toString(), getContentPathSafe(file));
throw iioException; throw iioException;
} }
@ -613,7 +610,7 @@ public class ImageUtils {
reader.dispose(); reader.dispose();
} }
} else { } else {
IIOException iioException = new IIOException(NO_IMAGE_READER_FOUND_FOR_ + getContentPathSafe(file)); IIOException iioException = new IIOException("No ImageReader found.");
LOGGER.log(Level.WARNING, errorTemplate + iioException.toString(), getContentPathSafe(file)); LOGGER.log(Level.WARNING, errorTemplate + iioException.toString(), getContentPathSafe(file));
throw iioException; throw iioException;
@ -646,18 +643,19 @@ public class ImageUtils {
*/ */
static private class GetThumbnailTask extends ReadImageTaskBase { static private class GetThumbnailTask extends ReadImageTaskBase {
private static final String FAILED_TO_READ_IMAGE_FOR_THUMBNAIL_GENERATION = "Failed to read image for thumbnail generation."; //NOI18N NON-NLS private static final String FAILED_TO_READ_IMAGE_FOR_THUMBNAIL_GENERATION = "Failed to read {0} for thumbnail generation."; //NOI18N NON-NLS
private final int iconSize; private final int iconSize;
private final File cacheFile; private final File cacheFile;
private final boolean defaultOnFailure; private final boolean defaultOnFailure;
// @NbBundle.Messages({"# {0} - file name", @NbBundle.Messages({"# {0} - file name",
// "GetOrGenerateThumbnailTask.loadingThumbnailFor=Loading thumbnail for {0}", "# {0} - file name", "GetOrGenerateThumbnailTask.loadingThumbnailFor=Loading thumbnail for {0}",
// "GetOrGenerateThumbnailTask.generatingPreviewFor=Generating preview for {0}"}) "# {0} - file name",
"GetOrGenerateThumbnailTask.generatingPreviewFor=Generating preview for video {0}"})
private GetThumbnailTask(AbstractFile file, int iconSize, boolean defaultOnFailure) { private GetThumbnailTask(AbstractFile file, int iconSize, boolean defaultOnFailure) {
super(file); super(file);
updateMessage(NbBundle.getMessage(this.getClass(), "ImageUtils.GetOrGenerateThumbnailTask.loadingThumbnailFor", file.getName())); updateMessage(Bundle.GetOrGenerateThumbnailTask_loadingThumbnailFor(file.getName()));
this.iconSize = iconSize; this.iconSize = iconSize;
this.defaultOnFailure = defaultOnFailure; this.defaultOnFailure = defaultOnFailure;
this.cacheFile = getCachedThumbnailLocation(file.getId()); this.cacheFile = getCachedThumbnailLocation(file.getId());
@ -678,36 +676,39 @@ public class ImageUtils {
if (nonNull(cachedThumbnail) && cachedThumbnail.getWidth() == iconSize) { if (nonNull(cachedThumbnail) && cachedThumbnail.getWidth() == iconSize) {
return SwingFXUtils.toFXImage(cachedThumbnail, null); return SwingFXUtils.toFXImage(cachedThumbnail, null);
} }
} catch (IOException ex) { } catch (Exception ex) {
LOGGER.log(Level.WARNING, "ImageIO had a problem reading thumbnail for image {0}: " + ex.toString(), ImageUtils.getContentPathSafe(file)); //NOI18N NON-NLS LOGGER.log(Level.WARNING, "ImageIO had a problem reading the cached thumbnail for {0}: " + ex.toString(), ImageUtils.getContentPathSafe(file)); //NOI18N NON-NLS
cacheFile.delete(); //since we can't read the file we might as well delete it.
} }
} }
if (isCancelled()) { if (isCancelled()) {
return null; return null;
} }
//There was no correctly-sized cached thumbnail so make one. //There was no correctly-sized cached thumbnail so make one.
BufferedImage thumbnail = null; BufferedImage thumbnail = null;
if (VideoUtils.isVideoThumbnailSupported(file)) { if (VideoUtils.isVideoThumbnailSupported(file)) {
if (openCVLoaded) { if (openCVLoaded) {
updateMessage(NbBundle.getMessage(this.getClass(), "ImageUtils.GetOrGenerateThumbnailTask.generatingPreviewFor", file.getName())); updateMessage(Bundle.GetOrGenerateThumbnailTask_generatingPreviewFor(file.getName()));
thumbnail = VideoUtils.generateVideoThumbnail(file, iconSize); thumbnail = VideoUtils.generateVideoThumbnail(file, iconSize);
} }
if (null == thumbnail) { if (null == thumbnail) {
if (defaultOnFailure) { if (defaultOnFailure) {
thumbnail = DEFAULT_THUMBNAIL; thumbnail = DEFAULT_THUMBNAIL;
} else { } else {
throw new IIOException("Failed to generate thumbnail for video file."); throw new IIOException("Failed to generate a thumbnail for " + getContentPathSafe(file));
} }
} }
} else { } else {
//read the image into a buffered image. //read the image into a buffered image.
//TODO: I don't like this, we just converted it from BufferedIamge to fx Image -jm
BufferedImage bufferedImage = SwingFXUtils.fromFXImage(readImage(), null); BufferedImage bufferedImage = SwingFXUtils.fromFXImage(readImage(), null);
if (null == bufferedImage) { if (null == bufferedImage) {
LOGGER.log(Level.WARNING, FAILED_TO_READ_IMAGE_FOR_THUMBNAIL_GENERATION); String msg = MessageFormat.format(FAILED_TO_READ_IMAGE_FOR_THUMBNAIL_GENERATION, getContentPathSafe(file));
throw new IIOException(FAILED_TO_READ_IMAGE_FOR_THUMBNAIL_GENERATION); LOGGER.log(Level.WARNING, msg);
throw new IIOException(msg);
} }
updateProgress(-1, 1); updateProgress(-1, 1);
@ -716,23 +717,21 @@ public class ImageUtils {
thumbnail = ScalrWrapper.resizeFast(bufferedImage, iconSize); thumbnail = ScalrWrapper.resizeFast(bufferedImage, iconSize);
} catch (IllegalArgumentException | OutOfMemoryError e) { } catch (IllegalArgumentException | OutOfMemoryError e) {
// if resizing does not work due to extreme aspect ratio or oom, crop the image instead. // if resizing does not work due to extreme aspect ratio or oom, crop the image instead.
LOGGER.log(Level.WARNING, "Could not scale image {0}: " + e.toString() + ". Attemptying to crop {0} instead", ImageUtils.getContentPathSafe(file)); //NOI18N NON-NLS LOGGER.log(Level.WARNING, "Cropping {0}, because it could not be scaled: " + e.toString(), ImageUtils.getContentPathSafe(file)); //NOI18N NON-NLS
final int height = bufferedImage.getHeight(); final int height = bufferedImage.getHeight();
final int width = bufferedImage.getWidth(); final int width = bufferedImage.getWidth();
if (iconSize < height || iconSize < width) { if (iconSize < height || iconSize < width) {
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 {
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 image {0}: " + cropException.toString(), ImageUtils.getContentPathSafe(file)); //NOI18N NON-NLS LOGGER.log(Level.WARNING, "Could not crop {0}: " + cropException.toString(), ImageUtils.getContentPathSafe(file)); //NOI18N NON-NLS
throw cropException;
} }
} }
} catch (Exception e) { } catch (Exception e) {
LOGGER.log(Level.WARNING, "Could not scale image {0}: " + e.toString(), ImageUtils.getContentPathSafe(file)); //NOI18N NON-NLS LOGGER.log(Level.WARNING, "Could not scale {0}: " + e.toString(), ImageUtils.getContentPathSafe(file)); //NOI18N NON-NLS
throw e; throw e;
} }
} }
@ -744,7 +743,7 @@ public class ImageUtils {
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) && nonNull(thumbnail) && DEFAULT_THUMBNAIL != thumbnail) { if ((cacheFile != null) && thumbnail != null && DEFAULT_THUMBNAIL != thumbnail) {
saveThumbnail(thumbnail); saveThumbnail(thumbnail);
} }
@ -790,16 +789,16 @@ public class ImageUtils {
/** /**
* A task that reads the content of a AbstractFile as a javafx Image. * A task that reads the content of a AbstractFile as a javafx Image.
*/ */
@NbBundle.Messages({
"# {0} - file name",
"LoadImageTask.mesageText=Reading image: {0}"})
static private class ReadImageTask extends ReadImageTaskBase { static private class ReadImageTask extends ReadImageTaskBase {
ReadImageTask(AbstractFile file) { ReadImageTask(AbstractFile file) {
super(file); super(file);
updateMessage(NbBundle.getMessage(this.getClass(), "ImageUtils.ReadImageTask.mesage.text", file.getName())); updateMessage(Bundle.LoadImageTask_mesageText(file.getName()));
} }
// @NbBundle.Messages({
// "# {0} - file name",
// "LoadImageTask.mesageText=Reading image: {0}"})
@Override @Override
protected javafx.scene.image.Image call() throws Exception { protected javafx.scene.image.Image call() throws Exception {
return readImage(); return readImage();
@ -811,70 +810,55 @@ public class ImageUtils {
*/ */
static private abstract class ReadImageTaskBase extends Task<javafx.scene.image.Image> implements IIOReadProgressListener { static private abstract class ReadImageTaskBase extends Task<javafx.scene.image.Image> implements IIOReadProgressListener {
private static final String IMAGE_UTILS_COULD_NOT_READ_UNSUPPORTE_OR_CORRUPT = "ImageUtils could not read {0}. It may be unsupported or corrupt"; //NOI18N NON-NLS private static final String IMAGEIO_COULD_NOT_READ_UNSUPPORTE_OR_CORRUPT = "ImageIO could not read {0}. It may be unsupported or corrupt"; //NOI18N NON-NLS
final AbstractFile file; final AbstractFile file;
private ImageReader reader; // private ImageReader reader;
ReadImageTaskBase(AbstractFile file) { ReadImageTaskBase(AbstractFile file) {
this.file = file; this.file = file;
} }
protected javafx.scene.image.Image readImage() throws IOException { protected javafx.scene.image.Image readImage() throws IOException {
try (InputStream inputStream = new BufferedInputStream(new ReadContentInputStream(file));) { 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(new BufferedInputStream(new ReadContentInputStream(file)));
javafx.scene.image.Image image = new javafx.scene.image.Image(new BufferedInputStream(inputStream)); if (image.isError() == false) {
if (image.isError() == false) { return image;
return image;
}
//fall through to default image reading code if there was an error
} }
if (isCancelled()) { //fall through to default image reading code if there was an error
return null; }
} if (isCancelled()) {
try (ImageInputStream input = ImageIO.createImageInputStream(inputStream)) { return null;
if (input == null) { }
throw new IIOException(COULD_NOT_CREATE_IMAGE_INPUT_STREAM);
}
Iterator<ImageReader> readers = ImageIO.getImageReaders(input);
//we use the first ImageReader, is there any point to trying the others? return getImageProperty(file, "ImageIO could not read {0}: ",
if (readers.hasNext()) { imageReader -> {
reader = readers.next(); imageReader.addIIOReadProgressListener(ReadImageTaskBase.this);
reader.addIIOReadProgressListener(this);
reader.setInput(input);
/* /*
* This is the important part, get or create a * This is the important part, get or create a
* ImageReadParam, create a destination image to hold * ImageReadParam, create a destination image to hold
* the decoded result, then pass that image with the * the decoded result, then pass that image with the
* param. * param.
*/ */
ImageReadParam param = reader.getDefaultReadParam(); ImageReadParam param = imageReader.getDefaultReadParam();
BufferedImage bufferedImage = imageReader.getImageTypes(0).next().createBufferedImage(imageReader.getWidth(0), imageReader.getHeight(0));
BufferedImage bufferedImage = reader.getImageTypes(0).next().createBufferedImage(reader.getWidth(0), reader.getHeight(0));
param.setDestination(bufferedImage); param.setDestination(bufferedImage);
try { try {
bufferedImage = reader.read(0, param); //should always be same bufferedImage object bufferedImage = imageReader.read(0, param); //should always be same bufferedImage object
} catch (IOException iOException) { } catch (IOException iOException) {
// Ignore this exception or display a warning or similar, for exceptions happening during decoding LOGGER.log(Level.WARNING, IMAGEIO_COULD_NOT_READ_UNSUPPORTE_OR_CORRUPT + ": " + iOException.toString(), ImageUtils.getContentPathSafe(file)); //NOI18N
LOGGER.log(Level.WARNING, IMAGE_UTILS_COULD_NOT_READ_UNSUPPORTE_OR_CORRUPT + ": " + iOException.toString(), ImageUtils.getContentPathSafe(file)); //NOI18N
} finally { } finally {
reader.removeIIOReadProgressListener(this); imageReader.removeIIOReadProgressListener(ReadImageTaskBase.this);
reader.dispose();
} }
if (isCancelled()) { if (isCancelled()) {
return null; return null;
} }
return SwingFXUtils.toFXImage(bufferedImage, null); return SwingFXUtils.toFXImage(bufferedImage, null);
} else { });
throw new IIOException(NO_IMAGE_READER_FOUND_FOR_ + ImageUtils.getContentPathSafe(file));
}
}
}
} }
@Override @Override
public void imageProgress(ImageReader source, float percentageDone) { public void imageProgress(ImageReader reader, float percentageDone) {
//update this task with the progress reported by ImageReader.read //update this task with the progress reported by ImageReader.read
updateProgress(percentageDone, 100); updateProgress(percentageDone, 100);
if (isCancelled()) { if (isCancelled()) {
@ -890,11 +874,11 @@ public class ImageUtils {
try { try {
javafx.scene.image.Image fxImage = get(); javafx.scene.image.Image fxImage = get();
if (fxImage == null) { if (fxImage == null) {
LOGGER.log(Level.WARNING, IMAGE_UTILS_COULD_NOT_READ_UNSUPPORTE_OR_CORRUPT, ImageUtils.getContentPathSafe(file)); LOGGER.log(Level.WARNING, IMAGEIO_COULD_NOT_READ_UNSUPPORTE_OR_CORRUPT, ImageUtils.getContentPathSafe(file));
} else { } else {
if (fxImage.isError()) { if (fxImage.isError()) {
//if there was somekind of error, log it //if there was somekind of error, log it
LOGGER.log(Level.WARNING, IMAGE_UTILS_COULD_NOT_READ_UNSUPPORTE_OR_CORRUPT + ": " + ObjectUtils.toString(fxImage.getException()), ImageUtils.getContentPathSafe(file)); LOGGER.log(Level.WARNING, IMAGEIO_COULD_NOT_READ_UNSUPPORTE_OR_CORRUPT + ": " + ObjectUtils.toString(fxImage.getException()), ImageUtils.getContentPathSafe(file));
} }
} }
} catch (InterruptedException | ExecutionException ex) { } catch (InterruptedException | ExecutionException ex) {
@ -905,7 +889,7 @@ public class ImageUtils {
@Override @Override
protected void failed() { protected void failed() {
super.failed(); super.failed();
LOGGER.log(Level.WARNING, IMAGE_UTILS_COULD_NOT_READ_UNSUPPORTE_OR_CORRUPT + ": " + ObjectUtils.toString(getException()), ImageUtils.getContentPathSafe(file)); LOGGER.log(Level.WARNING, IMAGEIO_COULD_NOT_READ_UNSUPPORTE_OR_CORRUPT + ": " + ObjectUtils.toString(getException()), ImageUtils.getContentPathSafe(file));
} }
@Override @Override