19 package org.sleuthkit.autopsy.modules.exif;
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.io.InputStream;
32 import java.util.ArrayList;
33 import java.util.Collection;
34 import java.util.Date;
35 import java.util.concurrent.atomic.AtomicInteger;
36 import java.util.logging.Level;
37 import org.openide.util.NbBundle;
74 jobId = context.getJobId();
79 throw new IngestModuleException(NbBundle.getMessage(
this.getClass(),
"ExifParserFileIngestModule.startUp.fileTypeDetectorInitializationException.msg"));
90 if (content.
isFile() ==
false) {
100 final int filesProcessedValue = filesProcessed.incrementAndGet();
101 if ((filesToFire) && (filesProcessedValue % 1000 == 0)) {
111 return processFile(content);
115 InputStream in = null;
116 BufferedInputStream bin = null;
120 bin =
new BufferedInputStream(in);
122 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
123 Metadata metadata = ImageMetadataReader.readMetadata(bin,
true);
126 ExifSubIFDDirectory exifDir = metadata.getDirectory(ExifSubIFDDirectory.class);
127 if (exifDir != null) {
128 Date date = exifDir.getDate(ExifSubIFDDirectory.TAG_DATETIME_ORIGINAL);
135 GpsDirectory gpsDir = metadata.getDirectory(GpsDirectory.class);
136 if (gpsDir != null) {
137 GeoLocation loc = gpsDir.getGeoLocation();
139 double latitude = loc.getLatitude();
140 double longitude = loc.getLongitude();
141 attributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_GEO_LATITUDE.getTypeID(), ExifParserModuleFactory.getModuleName(), latitude));
142 attributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE.getTypeID(), ExifParserModuleFactory.getModuleName(), longitude));
145 Rational altitude = gpsDir.getRational(GpsDirectory.TAG_GPS_ALTITUDE);
146 if (altitude != null) {
147 attributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_GEO_ALTITUDE.getTypeID(), ExifParserModuleFactory.getModuleName(), altitude.doubleValue()));
152 ExifIFD0Directory devDir = metadata.getDirectory(ExifIFD0Directory.class);
153 if (devDir != null) {
154 String model = devDir.getString(ExifIFD0Directory.TAG_MODEL);
155 if (model != null && !model.isEmpty()) {
156 attributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_MODEL.getTypeID(), ExifParserModuleFactory.getModuleName(), model));
159 String make = devDir.getString(ExifIFD0Directory.TAG_MAKE);
160 if (make != null && !make.isEmpty()) {
161 attributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DEVICE_MAKE.getTypeID(), ExifParserModuleFactory.getModuleName(), make));
166 if (!attributes.isEmpty()) {
167 BlackboardArtifact bba = f.
newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF);
172 return ProcessResult.OK;
173 }
catch (TskCoreException ex) {
174 logger.log(Level.WARNING,
"Failed to create blackboard artifact for exif metadata ({0}).", ex.getLocalizedMessage());
175 return ProcessResult.ERROR;
176 }
catch (ImageProcessingException ex) {
177 logger.log(Level.WARNING,
"Failed to process the image file: {0}/{1}({2})",
new Object[]{f.getParentPath(), f.getName(), ex.getLocalizedMessage()});
178 return ProcessResult.ERROR;
179 }
catch (IOException ex) {
180 logger.log(Level.WARNING,
"IOException when parsing image file: " + f.
getParentPath() +
"/" + f.
getName(), ex);
181 return ProcessResult.ERROR;
190 }
catch (IOException ex) {
191 logger.log(Level.WARNING,
"Failed to close InputStream.", ex);
192 return ProcessResult.ERROR;
208 if (mimeType != null) {
209 return fileTypeDetector.
getFileType(f).equals(
"image/jpeg");
214 logger.log(Level.SEVERE,
"Failed to detect file type", ex);
synchronized long decrementAndGet(long jobId)
void addAttributes(Collection< BlackboardAttribute > attributes)
void startUp(IngestJobContext context)
static final IngestModuleReferenceCounter refCounter
TskData.TSK_DB_FILES_TYPE_ENUM getType()
ProcessResult process(AbstractFile content)
synchronized long incrementAndGet(long jobId)
TskData.FileKnown getKnown()
static final Logger logger
final IngestServices services
void fireModuleDataEvent(ModuleDataEvent moduleDataEvent)
volatile boolean filesToFire
BlackboardArtifact newArtifact(int artifactTypeID)
final AtomicInteger filesProcessed
FileTypeDetector fileTypeDetector
String getFileType(AbstractFile file)
boolean parsableFormat(AbstractFile f)
static Logger getLogger(String name)
static synchronized IngestServices getInstance()