All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ForensicsToolbox.ReportManagement Maven / Gradle / Ivy

The newest version!
package ForensicsToolbox;

import java.awt.image.BufferedImage;
import java.io.*;
import java.io.File;
import java.net.URL;
import java.net.URLConnection;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;


import ThumbnailExtraction.thumbnailExtractor;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.mongodb.MongoClient;
import gps.gpsExtractor;
import metadataExtraction.metadataExtractor;
import org.mongodb.morphia.Datastore;
import org.mongodb.morphia.Morphia;
import pkg01_DoubleQuantization.DQDetector;
import pkg03_MedianDenoiseResidue.MedianNoiseExtractor;
import pkg06_ELA.JPEGELAExtractor;
import pkg07_waveletnoisemap.NoiseMapExtractor;
import pkg08_JPEGGhost.JPEGGhostExtractor;
import pkg14_BlockArtifact.BLKArtifactExtractor;

import javax.imageio.ImageIO;

/**
 * Created by marzampoglou on 11/19/15.
 */
public class ReportManagement {
    static int NumberOfThreads=7; //DQ, Noise, Ghost, ELA, Metadata, BLK, MedianNoise
    static long ComputationTimeoutLimit=60000;
    static int MaxGhostImageSmallDimension=768;
    static int numGhostThreads=5;
    private static ExecutorService threadpool;

    public static String DownloadURL(String URLIn, String FolderOut, String MongoHostIP) {

        MongoClient mongoclient = new MongoClient(MongoHostIP, 27017);
        Morphia morphia = new Morphia();
        morphia.map(ForensicReport.class).map(DQReport.class);
        Datastore ds = new Morphia().createDatastore(mongoclient, "ForensicDatabase");
        ds.ensureCaps();

        String URLHash = null;
        try {
            URLHash = buildURLHash(URLIn);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(URLHash);

        String BaseFolder = FolderOut + URLHash + "/";

        ForensicReport Report = ds.get(ForensicReport.class, URLHash);
        if (Report != null) {
            System.out.println("Exists");
            //JsonParser parser = new JsonParser();
            //JsonObject ExtractedMetadataReport = parser.parse(Report.MetadataStringReport).getAsJsonObject();
            //System.out.println(ExtractedMetadataReport.toString());
        } else {
            Report = new ForensicReport();
            Report.id = URLHash;
            //ds.save(Report);
            try {
                File WriteFolder=new File(BaseFolder);
                if (!WriteFolder.exists())
                    WriteFolder.mkdirs();
                DownloadFile(URLIn, BaseFolder);
                Report.SourceImage = BaseFolder + "Raw";
                Report.DisplayImage = BaseFolder + "Display.jpg";
                Report.SourceURL = URLIn;
                Report.status = "Downloaded";
                ds.save(Report);
            } catch (Exception e) {
                //e.printStackTrace();
                System.out.println("ERROR: The requested URL does not respond or does not exist. Exiting.");
                //ds.delete(ForensicReport.class, URLHash);
                return "URL_ERROR";
            }
        }
        mongoclient.close();
        return URLHash;
    }

    public static String CreateReport(String URLHash, String MongoHostIP, String FolderOut, int MaxGhostImageSmallDimension, int numGhostThreads, long ComputationTimeoutLimit) {
        return ReportCalculation(URLHash, MongoHostIP, FolderOut, MaxGhostImageSmallDimension, numGhostThreads, ComputationTimeoutLimit);
    }

    public static String CreateReport(String URLHash, String MongoHostIP, String FolderOut) {
        return ReportCalculation(URLHash, MongoHostIP, FolderOut, MaxGhostImageSmallDimension, numGhostThreads, ComputationTimeoutLimit);
    }

    public static String ReportCalculation(String URLHash, String MongoHostIP, String FolderOut, int MaxGhostImageSmallDimension, int numGhostThreads, long ComputationTimeoutLimit){
        String  OutMessage="COMPLETEDSUCCESSFULLY";
        threadpool = Executors.newFixedThreadPool(NumberOfThreads);
        MongoClient mongoclient = new MongoClient(MongoHostIP, 27017);        Morphia morphia = new Morphia();
        morphia.map(ForensicReport.class).map(DQReport.class);
        Datastore ds = new Morphia().createDatastore(mongoclient, "ForensicDatabase");
        ds.ensureCaps();
        String BaseFolder = FolderOut + URLHash + "/";
        ForensicReport Report = ds.get(ForensicReport.class, URLHash);
        if (Report == null) {
            return "HASHNOTFOUND";
        }
        if (Report.status.equalsIgnoreCase("Processing")) {
            return "ALREADYPROCESSING";
        }
        if (Report.status.equalsIgnoreCase("Done")) {
            return "PROCESSINGALREADYCOMPLETE";
        }
            Report.status="Processing";
            DQReport DQ=new DQReport();
            ELAReport ELA=new ELAReport();
            GhostReport Ghost=new GhostReport();
            NoiseDWReport NoiseDW=new NoiseDWReport();
            BLKReport BLK=new BLKReport();
            MedianNoiseReport MedianNoise=new MedianNoiseReport();
            GPSReport GPS = new GPSReport();

            File DQOutputfile = new File(BaseFolder,"DQOutput.png");
            File DWNoiseOutputfile = new File(BaseFolder,"DWNoiseOutput.png");
            File ghostOutputfile;
            File ELAOutputfile = new File(BaseFolder,"ELAOutput.png");
            File BLKOutputfile = new File(BaseFolder,"BLKOutput.png");
            File MedianNoiseOutputFile = new File(BaseFolder, "MedianNoiseOutput.png");

            try {
            if (ImageIO.read(new File(Report.SourceImage)).getColorModel().hasAlpha()) {
                //If image has an alpha channel, then assume transparent PNG -No point in processing it
                BufferedImage TransparencyNotAccepted=ArtificialImages.TransparentPNGNotAccepted();
                ImageIO.write(TransparencyNotAccepted, "png", DQOutputfile);
                DQ.Map=DQOutputfile.getCanonicalPath();
                DQ.completed=true;
                Report.DQ_Report=DQ;
                ImageIO.write(TransparencyNotAccepted, "png", DQOutputfile);
                NoiseDW.Map = DWNoiseOutputfile.getCanonicalPath();
                NoiseDW.completed=true;
                Report.NoiseDW_Report=NoiseDW;
                ghostOutputfile=new File(BaseFolder, "GhostOutput" + String.format("%02d", 0) + ".png");
                ImageIO.write(TransparencyNotAccepted, "png", ghostOutputfile);
                Ghost.Maps.add(ghostOutputfile.getCanonicalPath());
                Ghost.Differences.add((float) 0.0);
                Ghost.Qualities.add(0);
                Ghost.MinValues.add((float) 0.0);
                Ghost.MaxValues.add((float) 0.0);
                Ghost.completed=true;
                Report.Ghost_Report=Ghost;
                ImageIO.write(TransparencyNotAccepted, "png", DWNoiseOutputfile);
                ELA.Map = ELAOutputfile.getCanonicalPath();
                ELA.completed=true;
                Report.ELA_Report=ELA;
                ImageIO.write(TransparencyNotAccepted, "png", DQOutputfile);
                BLK.Map=BLKOutputfile.getCanonicalPath();
                BLK.completed=true;
                Report.BLK_Report=BLK;
                ImageIO.write(TransparencyNotAccepted, "png", BLKOutputfile);
                MedianNoise.Map=MedianNoiseOutputFile.getCanonicalPath();
                MedianNoise.completed=true;
                Report.MedianNoise_Report=MedianNoise;
                ds.save(Report);
            } else {
                Boolean DQSaved=false, NoiseDWSaved=false, GhostSaved=false, ELASaved=false, BLKSaved=false, MedianNoiseSaved=false;
                DQThread DQtask = new DQThread(Report.SourceImage,DQOutputfile);
                Future DQfuture = threadpool.submit(DQtask);
                NoiseDWThread NoiseDWtask = new NoiseDWThread(Report.SourceImage,DWNoiseOutputfile);
                Future NoiseDWfuture = threadpool.submit(NoiseDWtask);
                GhostThread Ghosttask = new GhostThread(Report.SourceImage,BaseFolder, MaxGhostImageSmallDimension, numGhostThreads);
                Future Ghostfuture = threadpool.submit(Ghosttask);
                ELAThread ELAtask = new ELAThread(Report.SourceImage,ELAOutputfile);
                Future ELAfuture = threadpool.submit(ELAtask);
                BLKThread BLKtask = new BLKThread(Report.SourceImage,BLKOutputfile);
                Future BLKfuture = threadpool.submit(BLKtask);
                MedianNoiseThread MedianNoisetask = new MedianNoiseThread(Report.SourceImage,MedianNoiseOutputFile);
                Future MedianNoisefuture = threadpool.submit(MedianNoisetask);

                Long startTime=System.currentTimeMillis();
                metadataExtractor metaExtractor;
                metaExtractor=new metadataExtractor(Report.SourceImage);
                JsonObject MetadataReport=metaExtractor.MetadataReport;
                MetadataReport.addProperty("completed", true);
                Report.MetadataStringReport = MetadataReport.toString();
                ds.save(Report);

                gpsExtractor GPSEx=new gpsExtractor(MetadataReport);
                GPS.completed=true;
                GPS.exists=GPSEx.exists;
                GPS.latitude=GPSEx.latitude;
                GPS.longitude=GPSEx.longitude;
                Report.GPS_Report=GPS;
                ds.save(Report);

                ThumbnailReport Thumbnail=new ThumbnailReport();
                thumbnailExtractor thumbExtractor;
                thumbExtractor = new thumbnailExtractor(Report.SourceImage);
                Thumbnail.NumberOfThumbnails=thumbExtractor.NumberOfThumbnails;
                File ThumbFile;
                for (int ThumbInd=0; ThumbInd ComputationTimeoutLimit){
                        System.out.println("Computation timed out");
                        OutMessage="TIMEDOUT";
                        break;
                    }
                }
                threadpool.shutdown();
            }
            }
            catch (Exception e) {
                threadpool.shutdown();
                e.printStackTrace();
            }
        Report.status="Done";
        ds.save(Report);
        System.out.println("Will now close mongodb connection");
        mongoclient.close();
        return OutMessage;
        }


    public static ForensicReport GetReport(String URLHash, String MongoHostIP){
        MongoClient mongoclient = new MongoClient(MongoHostIP, 27017);
        Morphia morphia = new Morphia();
        morphia.map(ForensicReport.class).map(DQReport.class);
        Datastore ds = new Morphia().createDatastore(mongoclient, "ForensicDatabase");
        ds.ensureCaps();
        ForensicReport Report = ds.get(ForensicReport.class, URLHash);
        if (Report!=null) {
            JsonParser parser = new JsonParser();
            JsonObject tmpJson = parser.parse(Report.MetadataStringReport).getAsJsonObject();
            GsonBuilder builder = new GsonBuilder();
            Report.MetadataObjectReport = builder.create().fromJson(tmpJson, Object.class);
        }
        mongoclient.close();
        return Report;
    }

    private static void DownloadFile(String URLIn, String FolderOut) throws IOException {
        URL ImageURL = new URL(URLIn);
        File LocalDir = new File(FolderOut);
        LocalDir.mkdir();
        File ImageFile = new File (FolderOut,"Raw");
        InputStream inputStream = null;
        URLConnection urlConnection = null;
        int noOfBytes = 0;
        byte[] byteChunk = new byte[4096];
        ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
        urlConnection = ImageURL.openConnection();
        urlConnection.addRequestProperty("User-Agent", "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.4; en-US; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2");
        urlConnection.connect();
        inputStream = urlConnection.getInputStream();
        while ((noOfBytes = inputStream.read(byteChunk)) > 0) {
            byteOutputStream.write(byteChunk, 0, noOfBytes);
        }
        OutputStream outputStream = new FileOutputStream(ImageFile);
        byteOutputStream.writeTo(outputStream);
        outputStream.close();

        BufferedImage DownloadedImage=ImageIO.read(ImageFile);
        ImageIO.write(DownloadedImage, "JPEG", new File(FolderOut , "Display.jpg"));
    }


    static String buildURLHash(String URLIn) throws UnsupportedEncodingException, NoSuchAlgorithmException {

        //Build a hash based on the URL -would be better to build it based on the file content itself, but that might cause
        // synchronization issues while waiting for the file to download
        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(URLIn.getBytes("UTF-8")); // Change this to "UTF-16" if needed
        byte[] digest = md.digest();
        String URLHash = String.format("%032x", new java.math.BigInteger(1, digest));
        return URLHash;
    }

    private static class DQThread implements Callable {
        String SourceFile="";
        File Outputfile=null;
        public DQThread(String SourceFile,File Outputfile){
            this.SourceFile=SourceFile;
            this.Outputfile=Outputfile;
        }
        @Override
        public DQReport call() {
            DQReport output=null;
            try {
                output=DQCalculation();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return output;
        }
        public DQReport DQCalculation() throws IOException {
            DQReport DQ=new DQReport();
            DQDetector dqDetector;
            dqDetector = new DQDetector(SourceFile);
            ImageIO.write(dqDetector.DisplaySurface, "png", Outputfile);
            DQ.Map = Outputfile.getCanonicalPath();
            DQ.MaxValue = dqDetector.maxProbValue;
            DQ.MinValue = dqDetector.minProbValue;
            DQ.completed=true;
            return DQ;
        }
    }

    private static class NoiseDWThread implements Callable {
        String SourceFile="";
        File Outputfile=null;
        public NoiseDWThread(String SourceFile,File Outputfile){
            this.SourceFile=SourceFile;
            this.Outputfile=Outputfile;
        }
        @Override
        public NoiseDWReport call() {
            NoiseDWReport output=null;
            try {
                output=NoiseDWCalculation();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return output;
        }
        public NoiseDWReport NoiseDWCalculation() throws IOException {
            NoiseDWReport NoiseDW=new NoiseDWReport();
            NoiseMapExtractor noiseExtractor;
            noiseExtractor = new NoiseMapExtractor(SourceFile);
            ImageIO.write(noiseExtractor.DisplaySurface, "png", Outputfile);
            NoiseDW.Map = Outputfile.getCanonicalPath();
            NoiseDW.MaxValue = noiseExtractor.maxNoiseValue;
            NoiseDW.MinValue = noiseExtractor.minNoiseValue;
            NoiseDW.completed=true;
            return NoiseDW;
        }
    }

    private static class GhostThread implements Callable {
        String SourceFile="";
        String BaseFolder="";
        int MaxGhostImageSmallDimension;
        int numGhostThreads;
        public GhostThread(String SourceFile,String BaseFolder, int MaxGhostImageSmallDimension, int numGhostThreads){
            this.SourceFile=SourceFile;
            this.BaseFolder=BaseFolder;
            this.MaxGhostImageSmallDimension= MaxGhostImageSmallDimension;
            this.numGhostThreads=numGhostThreads;
        }
        @Override
        public GhostReport call() {
            GhostReport output=null;
            try {
                output=GhostCalculation(MaxGhostImageSmallDimension, numGhostThreads);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return output;
        }
        public GhostReport GhostCalculation(int MaxImageSmallDimension,int numThreads) throws IOException {
            File ghostOutputfile;
            GhostReport Ghost=new GhostReport();
            JPEGGhostExtractor ghostExtractor;
            ghostExtractor = new JPEGGhostExtractor(SourceFile, MaxImageSmallDimension, numThreads);
            BufferedImage GhostMap;
            for (int GhostMapInd=0;GhostMapInd




© 2015 - 2024 Weber Informatics LLC | Privacy Policy