Autopsy  3.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
ImageUtils.java
Go to the documentation of this file.
1  /*
2  *
3  * Autopsy Forensic Browser
4  *
5  * Copyright 2012 Basis Technology Corp.
6  *
7  * Copyright 2012 42six Solutions.
8  * Contact: aebadirad <at> 42six <dot> com
9  * Project Contact/Architect: carrier <at> sleuthkit <dot> org
10  *
11  * Licensed under the Apache License, Version 2.0 (the "License");
12  * you may not use this file except in compliance with the License.
13  * You may obtain a copy of the License at
14  *
15  * http://www.apache.org/licenses/LICENSE-2.0
16  *
17  * Unless required by applicable law or agreed to in writing, software
18  * distributed under the License is distributed on an "AS IS" BASIS,
19  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  * See the License for the specific language governing permissions and
21  * limitations under the License.
22  */
23 package org.sleuthkit.autopsy.coreutils;
24 
25 import java.awt.Image;
26 import java.awt.image.BufferedImage;
27 import java.io.File;
28 import java.io.IOException;
29 import java.io.InputStream;
30 import java.util.ArrayList;
31 import java.util.Arrays;
32 import java.util.List;
33 import java.util.logging.Level;
34 import javax.imageio.ImageIO;
35 import javax.swing.ImageIcon;
44 
49 public class ImageUtils {
50  public static final int ICON_SIZE_SMALL = 50;
51  public static final int ICON_SIZE_MEDIUM = 100;
52  public static final int ICON_SIZE_LARGE = 200;
53  private static final Logger logger = Logger.getLogger(ImageUtils.class.getName());
54  private static final Image DEFAULT_ICON = new ImageIcon("/org/sleuthkit/autopsy/images/file-icon.png").getImage(); //NON-NLS
55  private static final List<String> SUPP_EXTENSIONS = Arrays.asList(ImageIO.getReaderFileSuffixes());
56  private static final List<String> SUPP_MIME_TYPES = new ArrayList<>(Arrays.asList(ImageIO.getReaderMIMETypes()));
57  static {
58  SUPP_MIME_TYPES.add("image/x-ms-bmp");
59  }
60 
65  public static Image getDefaultIcon() {
66  return DEFAULT_ICON;
67  }
68 
75  public static boolean thumbnailSupported(Content content) {
76  if (content instanceof AbstractFile == false) {
77  return false;
78  }
79 
80  AbstractFile f = (AbstractFile) content;
81  if (f.getSize() == 0) {
82  return false;
83  }
84 
85  // check the blackboard for a file type attribute
86  try {
87  ArrayList <BlackboardAttribute> attributes = f.getGenInfoAttributes(ATTRIBUTE_TYPE.TSK_FILE_TYPE_SIG);
88  for (BlackboardAttribute attribute : attributes) {
89  if (SUPP_MIME_TYPES.contains(attribute.getValueString())) {
90  return true;
91  }
92  }
93  // if the file type is known and we don't support it, bail
94  if (attributes.size() > 0) {
95  return false;
96  }
97  }
98  catch (TskCoreException ex) {
99  logger.log(Level.WARNING, "Error while getting file signature from blackboard.", ex); //NON-NLS
100  }
101 
102  // if we have an extension, check it
103  final String extension = f.getNameExtension();
104  if (extension.equals("") == false) {
105  // Note: thumbnail generator only supports JPG, GIF, and PNG for now
106  if (SUPP_EXTENSIONS.contains(extension)) {
107  return true;
108  }
109  }
110 
111  // if no extension or one that is not for an image, then read the content
112  return isJpegFileHeader(f);
113  }
114 
115 
124  public static Image getIcon(Content content, int iconSize) {
125  Image icon;
126  // If a thumbnail file is already saved locally
127  // @@@ Bug here in that we do not refer to size in the cache.
128  File file = getFile(content.getId());
129  if (file.exists()) {
130  try {
131  BufferedImage bicon = ImageIO.read(file);
132  if (bicon == null) {
133  icon = DEFAULT_ICON;
134  } else if (bicon.getWidth() != iconSize) {
135  icon = generateAndSaveIcon(content, iconSize, file);
136  } else {
137  icon = bicon;
138  }
139  } catch (IOException ex) {
140  logger.log(Level.WARNING, "Error while reading image.", ex); //NON-NLS
141  icon = DEFAULT_ICON;
142  }
143  } else { // Make a new icon
144  icon = generateAndSaveIcon(content, iconSize, file);
145  }
146  return icon;
147  }
148 
156  public static File getIconFile(Content content, int iconSize) {
157  if (getIcon(content, iconSize) != null) {
158  return getFile(content.getId());
159  }
160  return null;
161  }
162 
169  // TODO: This should be private and be renamed to something like getCachedThumbnailLocation().
170  public static File getFile(long id) {
171  return new File(Case.getCurrentCase().getCacheDirectory() + File.separator + id + ".png");
172  }
173 
181  public static boolean isJpegFileHeader(AbstractFile file) {
182  if (file.getSize() < 100) {
183  return false;
184  }
185 
186  byte[] fileHeaderBuffer = new byte[2];
187  int bytesRead;
188  try {
189  bytesRead = file.read(fileHeaderBuffer, 0, 2);
190  } catch (TskCoreException ex) {
191  //ignore if can't read the first few bytes, not a JPEG
192  return false;
193  }
194  if (bytesRead != 2) {
195  return false;
196  }
197  /*
198  * Check for the JPEG header. Since Java bytes are signed, we cast them
199  * to an int first.
200  */
201  return (((fileHeaderBuffer[0] & 0xff) == 0xff) && ((fileHeaderBuffer[1] & 0xff) == 0xd8));
202  }
203 
204  public static boolean isPngFileHeader(AbstractFile file) {
205  if (file.getSize() < 10) {
206  return false;
207  }
208 
209  byte[] fileHeaderBuffer = new byte[8];
210  int bytesRead;
211  try {
212  bytesRead = file.read(fileHeaderBuffer, 0, 8);
213  } catch (TskCoreException ex) {
214  //ignore if can't read the first few bytes, not an image
215  return false;
216  }
217  if (bytesRead != 8) {
218  return false;
219  }
220  /*
221  * Check for the header. Since Java bytes are signed, we cast them
222  * to an int first.
223  */
224  return (((fileHeaderBuffer[1] & 0xff) == 0x50) && ((fileHeaderBuffer[2] & 0xff) == 0x4E) &&
225  ((fileHeaderBuffer[3] & 0xff) == 0x47) && ((fileHeaderBuffer[4] & 0xff) == 0x0D) &&
226  ((fileHeaderBuffer[5] & 0xff) == 0x0A) && ((fileHeaderBuffer[6] & 0xff) == 0x1A) &&
227  ((fileHeaderBuffer[7] & 0xff) == 0x0A));
228  }
229 
230 
238  private static Image generateAndSaveIcon(Content content, int iconSize, File saveFile) {
239  Image icon = null;
240  try {
241  icon = generateIcon(content, iconSize);
242  if (icon == null) {
243  return DEFAULT_ICON;
244  } else {
245  if (saveFile.exists()) {
246  saveFile.delete();
247  }
248  ImageIO.write((BufferedImage) icon, "png", saveFile); //NON-NLS
249  }
250  } catch (IOException ex) {
251  logger.log(Level.WARNING, "Could not write cache thumbnail: " + content, ex); //NON-NLS
252  }
253  return icon;
254  }
255 
256  /*
257  * Generate and return a scaled image
258  */
259  private static BufferedImage generateIcon(Content content, int iconSize) {
260 
261  InputStream inputStream = null;
262  BufferedImage bi = null;
263  try {
264  inputStream = new ReadContentInputStream(content);
265  bi = ImageIO.read(inputStream);
266  if (bi == null) {
267  logger.log(Level.WARNING, "No image reader for file: " + content.getName()); //NON-NLS
268  return null;
269  }
270  BufferedImage biScaled = ScalrWrapper.resizeFast(bi, iconSize);
271 
272  return biScaled;
273  } catch (IllegalArgumentException e) {
274  // if resizing does not work due to extremely small height/width ratio,
275  // crop the image instead.
276  BufferedImage biCropped = ScalrWrapper.cropImage(bi, Math.min(iconSize, bi.getWidth()), Math.min(iconSize, bi.getHeight()));
277  return biCropped;
278  }
279  catch (OutOfMemoryError e) {
280  logger.log(Level.WARNING, "Could not scale image (too large): " + content.getName(), e); //NON-NLS
281  return null;
282  } catch (Exception e) {
283  logger.log(Level.WARNING, "Could not scale image: " + content.getName(), e); //NON-NLS
284  return null;
285  } finally {
286  if (inputStream != null) {
287  try {
288  inputStream.close();
289  } catch (IOException ex) {
290  logger.log(Level.WARNING, "Could not close input stream after resizing thumbnail: " + content.getName(), ex); //NON-NLS
291  }
292  }
293 
294  }
295  }
296 }
static File getIconFile(Content content, int iconSize)
static boolean isPngFileHeader(AbstractFile file)
static boolean thumbnailSupported(Content content)
Definition: ImageUtils.java:75
static Image getIcon(Content content, int iconSize)
static BufferedImage generateIcon(Content content, int iconSize)
static synchronized BufferedImage resizeFast(BufferedImage input, int size)
static boolean isJpegFileHeader(AbstractFile file)
static Image generateAndSaveIcon(Content content, int iconSize, File saveFile)
static final List< String > SUPP_EXTENSIONS
Definition: ImageUtils.java:55
static final List< String > SUPP_MIME_TYPES
Definition: ImageUtils.java:56
final int read(byte[] buf, long offset, long len)
ArrayList< BlackboardAttribute > getGenInfoAttributes(ATTRIBUTE_TYPE attr_type)
static Logger getLogger(String name)
Definition: Logger.java:131
static synchronized BufferedImage cropImage(BufferedImage input, int width, int height)

Copyright © 2012-2015 Basis Technology. Generated on: Mon Oct 19 2015
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.