diff --git a/src/META-INF/MANIFEST.MF b/src/META-INF/MANIFEST.MF new file mode 100644 index 0000000..984f7ae --- /dev/null +++ b/src/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: com.jankais3r.jPhotoDNA.Main + diff --git a/src/com/jankais3r/jPhotoDNA/Main.java b/src/com/jankais3r/jPhotoDNA/Main.java new file mode 100644 index 0000000..eb63892 --- /dev/null +++ b/src/com/jankais3r/jPhotoDNA/Main.java @@ -0,0 +1,49 @@ +package com.jankais3r.jPhotoDNA; + +import org.opencv.core.Mat; +import org.opencv.core.Core; +import org.opencv.imgcodecs.Imgcodecs; +import java.io.File; + +public class Main { + public static void main(String[] args) { + int argCount = args.length; + if(argCount == 2) { + String libPath = args[0]; + File libFile = new File(libPath); + if (libFile.isFile() && (libPath.endsWith("PhotoDNAx64.dll"))) { + String imagePath = args[1]; + File imageFile = new File(imagePath); + if (imageFile.isFile()) { + System.loadLibrary(Core.NATIVE_LIBRARY_NAME); + Imgcodecs imageCodecs = new Imgcodecs(); + Mat matImage = imageCodecs.imread(imagePath); + + PhotoDNA engine = new PhotoDNA(libPath); + byte[] hashBytes = engine.calculateHash(matImage); + + String hashString = ""; + for (int j = 0; j < 144; j++) { + hashString = hashString + (hashBytes[j] & 0xFF); + if (j + 1 != hashBytes.length) + hashString = hashString + ","; + } + + System.out.println(imagePath + "|" + hashString); + engine.releaseBuffer(); + } else { + System.out.println("Image file does not exist."); + System.exit(0); + } + } else { + System.out.println("Invalid path to PhotoDNAx64.dll."); + System.out.println("Run as: java -jar jPhotoDNA.jar PhotoDNAx64.dll image.jpg"); + System.exit(0); + } + } else { + System.out.println("Invalid argument count."); + System.out.println("Run as: java -jar jPhotoDNA.jar PhotoDNAx64.dll image.jpg"); + System.exit(0); + } + } +} diff --git a/src/com/jankais3r/jPhotoDNA/PhotoDNA.java b/src/com/jankais3r/jPhotoDNA/PhotoDNA.java new file mode 100644 index 0000000..2ec82d6 --- /dev/null +++ b/src/com/jankais3r/jPhotoDNA/PhotoDNA.java @@ -0,0 +1,36 @@ +package com.jankais3r.jPhotoDNA; + +import com.sun.jna.Native; +import com.sun.jna.Pointer; +import org.opencv.core.Mat; + +public class PhotoDNA { + private extendPhotoDNA photoDNA; + private Pointer functPointer; + + public PhotoDNA(String photoDnaLib) { + this.photoDNA = Native.load(photoDnaLib, extendPhotoDNA.class); + this.functPointer = this.photoDNA.RobustHashInitBuffer(16777216); + } + + public byte[] calculateHash(Mat matImage) { + byte[] byteImage = new byte[matImage.width() * matImage.height() * matImage.channels()]; + matImage.get(0, 0, byteImage); + + int ImageWidth = matImage.width(); + int ImageHeight = matImage.height(); + byte[] hashValue = new byte[144]; + if (ImageWidth * ImageHeight <= 16777216) { + int pitch = 0; + this.photoDNA.ComputeRobustHash(byteImage, ImageWidth, ImageHeight, pitch, hashValue, this.functPointer); + } else { + System.out.println("Does not support images over 16MP (4096x4096)."); + System.exit(0); + } + return hashValue; + } + + public void releaseBuffer() { + this.photoDNA.RobustHashReleaseBuffer(this.functPointer); + } +} diff --git a/src/com/jankais3r/jPhotoDNA/extendPhotoDNA.java b/src/com/jankais3r/jPhotoDNA/extendPhotoDNA.java new file mode 100644 index 0000000..80c0d45 --- /dev/null +++ b/src/com/jankais3r/jPhotoDNA/extendPhotoDNA.java @@ -0,0 +1,10 @@ +package com.jankais3r.jPhotoDNA; + +import com.sun.jna.Library; +import com.sun.jna.Pointer; + +public interface extendPhotoDNA extends Library { + Pointer RobustHashInitBuffer(int int0); + void RobustHashReleaseBuffer(Pointer pointer1); + int ComputeRobustHash(byte[] byteArray1, int int1, int int2, int int3, byte[] byteArray2, Pointer pointer1); +}