19 package org.sleuthkit.autopsy.modules.pictureanalyzer.impls;
21 import com.drew.imaging.ImageMetadataReader;
22 import com.drew.imaging.ImageProcessingException;
23 import com.drew.lang.GeoLocation;
24 import com.drew.lang.Rational;
25 import com.drew.metadata.Metadata;
26 import com.drew.metadata.exif.ExifIFD0Directory;
27 import com.drew.metadata.exif.ExifSubIFDDirectory;
28 import com.drew.metadata.exif.GpsDirectory;
29 import java.io.BufferedInputStream;
30 import java.io.IOException;
31 import java.util.ArrayList;
32 import java.util.Arrays;
33 import java.util.Collection;
34 import java.util.Date;
36 import java.util.HashSet;
37 import java.util.List;
38 import java.util.TimeZone;
39 import java.util.logging.Level;
40 import org.apache.commons.lang3.StringUtils;
41 import org.openide.util.NbBundle;
42 import org.openide.util.lookup.ServiceProvider;
73 "ExifProcessor.userContent.description=EXIF metadata data exists for this file."
80 final Collection<BlackboardAttribute> attributes =
new ArrayList<>();
81 final Metadata metadata = ImageMetadataReader.readMetadata(bin);
84 final ExifSubIFDDirectory exifDir = metadata.getFirstDirectoryOfType(ExifSubIFDDirectory.class);
85 if (exifDir != null) {
88 TimeZone timeZone = null;
91 if ((dataSource != null) && (dataSource instanceof
Image)) {
92 Image image = (Image) dataSource;
93 timeZone = TimeZone.getTimeZone(image.
getTimeZone());
96 logger.log(Level.INFO,
"Error getting time zones", ex);
99 final Date date = exifDir.getDate(ExifSubIFDDirectory.TAG_DATETIME_ORIGINAL, timeZone);
110 final GpsDirectory gpsDir = metadata.getFirstDirectoryOfType(GpsDirectory.class);
111 if (gpsDir != null) {
112 final GeoLocation loc = gpsDir.getGeoLocation();
118 final Rational altitude = gpsDir.getRational(GpsDirectory.TAG_ALTITUDE);
119 if (altitude != null) {
120 double alt = altitude.doubleValue();
121 if (Double.isInfinite(alt)) {
133 final ExifIFD0Directory devDir = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class);
134 if (devDir != null) {
135 final String model = devDir.getString(ExifIFD0Directory.TAG_MODEL);
136 if (StringUtils.isNotBlank(model)) {
140 final String make = devDir.getString(ExifIFD0Directory.TAG_MAKE);
141 if (StringUtils.isNotBlank(make)) {
153 List<BlackboardArtifact> artifacts =
new ArrayList<>();
158 attributes)).getAnalysisResult();
159 artifacts.add(exifArtifact);
168 Bundle.ExifProcessor_userContent_description())))
169 .getAnalysisResult();
170 artifacts.add(userSuspectedArtifact);
175 logger.log(Level.SEVERE, String.format(
"Error posting TSK_METADATA_EXIF and TSK_USER_CONTENT_SUSPECTED artifacts for %s (object ID = %d)", file.
getName(), file.
getId()), ex);
179 logger.log(Level.SEVERE, String.format(
"Error creating TSK_METADATA_EXIF and TSK_USER_CONTENT_SUSPECTED artifacts for %s (object ID = %d)", file.
getName(), file.
getId()), ex);
180 }
catch (IOException | ImageProcessingException ex) {
181 logger.log(Level.WARNING, String.format(
"Error parsing %s (object ID = %d), presumed corrupt", file.
getName(), file.
getId()), ex);
183 logger.log(Level.SEVERE, String.format(
"Error processing %s (object ID = %d)", file.
getName(), file.
getId()), ex);
189 return new HashSet<String>() {
static final Score SCORE_UNKNOWN
Blackboard getBlackboard()
void postArtifacts(Collection< BlackboardArtifact > artifacts, String moduleName)
void process(IngestJobContext context, AbstractFile file)
AnalysisResultAdded newAnalysisResult(BlackboardArtifact.Type artifactType, Score score, String conclusion, String configuration, String justification, Collection< BlackboardAttribute > attributesList)
static String getModuleName()
boolean artifactExists(Content content, BlackboardArtifact.Type artifactType, Collection< BlackboardAttribute > attributes)
static final Type TSK_METADATA_EXIF
static final Type TSK_USER_CONTENT_SUSPECTED
SleuthkitCase getSleuthkitCase()
boolean fileIngestIsCancelled()
synchronized static Logger getLogger(String name)
static Case getCurrentCaseThrows()
static final Score SCORE_NONE
Set< String > mimeTypes()