19 package org.sleuthkit.autopsy.modules.pictureanalyzer.impls;
21 import java.util.HashSet;
23 import java.util.logging.Level;
24 import java.util.Arrays;
25 import java.util.concurrent.TimeUnit;
28 import java.io.IOException;
29 import java.io.InputStream;
31 import java.nio.file.Files;
32 import java.nio.file.Path;
33 import java.nio.file.Paths;
34 import java.nio.file.attribute.BasicFileAttributes;
35 import java.text.MessageFormat;
36 import java.util.List;
37 import org.apache.commons.io.FileUtils;
39 import org.apache.commons.io.FilenameUtils;
41 import org.openide.util.lookup.ServiceProvider;
64 @ServiceProvider(service = PictureProcessor.class)
69 private static final String HEIC_MODULE_FOLDER =
"HEIC";
76 }
catch (UnsatisfiedLinkError ex) {
77 logger.log(Level.SEVERE,
"libheif native dependencies not found. HEIC functionality will be automatically disabled.", ex);
80 this.heifJNI = heifJNI;
86 if (heifJNI == null) {
94 if (file == null || file.
getId() <= 0) {
100 heifBytes =
new byte[is.available()];
104 if (heifBytes == null || heifBytes.length == 0) {
108 convertToJPEG(context, heifBytes, file);
109 }
catch (IOException ex) {
110 logger.log(Level.WARNING,
"I/O error encountered during HEIC photo processing.", ex);
112 logger.log(Level.SEVERE,
"Unable to add pictures as derived files.", ex);
114 logger.log(Level.WARNING,
"No open case!", ex);
128 Path moduleOutputFolder = Paths.get(moduleOutputDirectory,
130 String.valueOf(file.getId()));
132 if (!Files.exists(moduleOutputFolder)) {
133 Files.createDirectories(moduleOutputFolder);
136 return moduleOutputFolder;
142 Path outputFolder = createModuleOutputFolder(heicFile);
145 final Path outputFile = outputFolder.resolve(baseFileName +
".jpg");
147 if (context.fileIngestIsCancelled()) {
152 this.heifJNI.
convertToDisk(heifBytes, outputFile.toString());
153 }
catch (IllegalArgumentException | IllegalStateException ex) {
154 logger.log(Level.WARNING, MessageFormat.format(
"There was an error processing {0} (id: {1}).", heicFile.getName(), heicFile.getId()), ex);
156 }
catch (Throwable ex) {
157 logger.log(Level.SEVERE, MessageFormat.format(
"A severe error occurred while processing {0} (id: {1}).", heicFile.getName(), heicFile.getId()), ex);
161 if (context.fileIngestIsCancelled()) {
167 List<File> files = (List<File>) FileUtils.listFiles(outputFolder.toFile(),
new String[]{
"jpg",
"jpeg"},
true);
168 for (File file : files) {
169 if (context.fileIngestIsCancelled()) {
173 Path candidate = file.toPath();
175 final BasicFileAttributes attrs = Files.readAttributes(candidate, BasicFileAttributes.class);
176 final Path localCasePath = caseDirectory.relativize(candidate);
180 localCasePath.toString(), attrs.size(), 0L,
181 attrs.creationTime().to(TimeUnit.SECONDS),
182 attrs.lastAccessTime().to(TimeUnit.SECONDS),
183 attrs.lastModifiedTime().to(TimeUnit.SECONDS),
184 attrs.isRegularFile(), heicFile,
"",
187 context.addFilesToJob(Arrays.asList(jpegFile));
194 return new HashSet<String>() {
static HeifJNI getInstance()
String getCaseDirectory()
Set< String > mimeTypes()
DerivedFile addDerivedFile(String fileName, String localPath, long size, long ctime, long crtime, long atime, long mtime, boolean isFile, Content parentObj, String rederiveDetails, String toolName, String toolVersion, String otherDetails, TskData.EncodingType encodingType)
SleuthkitCase getSleuthkitCase()
String getModuleDirectory()
boolean fileIngestIsCancelled()
void convertToJPEG(IngestJobContext context, byte[] heifBytes, AbstractFile heicFile)
void fireModuleContentEvent(ModuleContentEvent moduleContentEvent)
Path createModuleOutputFolder(AbstractFile file)
native int convertToDisk(byte[] data, String jpgOutputPath)
static String escapeFileName(String fileName)
synchronized static Logger getLogger(String name)
static Case getCurrentCaseThrows()
void process(IngestJobContext context, AbstractFile file)
static synchronized IngestServices getInstance()