diff --git a/src/ArrayUtils.java b/src/ArrayUtils.java old mode 100644 new mode 100755 index 8612959..d7a981c --- a/src/ArrayUtils.java +++ b/src/ArrayUtils.java @@ -89,6 +89,7 @@ public class ArrayUtils */ public static byte[] unsign(byte[] b) { + if(b == null) return null; byte[] u = new byte[b.length]; for (int i = 0; i < b.length; i++) u[i] = (byte) (b[i] & 0xFF); diff --git a/src/Base64Wrapper.java b/src/Base64Wrapper.java old mode 100644 new mode 100755 diff --git a/src/Const.java b/src/Const.java old mode 100644 new mode 100755 index 1933612..4d38fb7 --- a/src/Const.java +++ b/src/Const.java @@ -13,6 +13,7 @@ public class Const public static final String EXIF = "EXIF"; public static final String STANDARDXMP = "StandardXMP"; public static final String EXTENDEDXMP = "ExtendedXMP"; + public static final String mimeJPG = "image/jpeg"; /** * Magical bytes that identify the file as JPG (FF D8) (length: 2) @@ -81,6 +82,16 @@ public class Const (byte) 0x68, (byte) 0x3a, (byte) 0x44, (byte) 0x61, (byte) 0x74, (byte) 0x61 }; + + /** + * Key for the MIME type of the depth map + * (GDepth:Mime) (length: 11) + */ + public static byte[] keyGDepthMIME = { + (byte) 0x47, (byte) 0x44, (byte) 0x65, (byte) 0x70, (byte) 0x74, + (byte) 0x68, (byte) 0x3a, (byte) 0x4D, (byte) 0x69, (byte) 0x6D, + (byte) 0x65 + }; /** * Key for the Base64 encoded unblurred jpg source image (Google camera will combine this with the depth information to render the blurred image) diff --git a/src/DepthMapNeedle.java b/src/DepthMapNeedle.java old mode 100644 new mode 100755 index 60bd9cd..40971b5 --- a/src/DepthMapNeedle.java +++ b/src/DepthMapNeedle.java @@ -14,13 +14,19 @@ public class DepthMapNeedle @Override public byte[] decode(byte[] data) { - return Base64.getDecoder().decode(data); + if(data != null) + return Base64.getDecoder().decode(data); + else + return null; } @Override public byte[] encode(byte[] data) { - return Base64.getEncoder().encode(data); + if(data != null) + return Base64.getEncoder().encode(data); + else + return null; } }; //No arguments given or '-h' as first argument -> show help text @@ -33,8 +39,8 @@ public class DepthMapNeedle { JPEG image = new JPEG(args[i], wrapper); if (image.exportDepthMap()) - System.out.println("Depthmap extracted for file "+args[i]+"."); - else System.err.println("There is no Depthmap in file "+args[i]); + System.out.println("Info: Depthmap extracted for file "+args[i]+"."); + else System.out.println("Warning: There is no Depthmap in file "+args[i]+"."); } } @@ -45,9 +51,9 @@ public class DepthMapNeedle { JPEG image = new JPEG(args[i], wrapper); if (image.exportSourceImage()) - System.out.println("Unblurred source image extracted for file "+args[i]+"."); + System.out.println("Info: Unblurred source image extracted for file "+args[i]+"."); else - System.err.println("There is no unblurred source image in file "+args[i]+". Maybe this photo has not been taken with the blur function?"); + System.out.println("Warning: There is no unblurred source image in file "+args[i]+". Maybe this photo has not been taken with Google Camera\'s blur function?"); } } @@ -59,9 +65,9 @@ public class DepthMapNeedle { JPEG image = new JPEG(args[i], wrapper); if (image.injectDepthMap(depthmap)) - System.out.println("Depthmap injected into file "+args[i]+"."); + System.out.println("Info: Depthmap injected into file "+args[i]+"."); else - System.err.println("Something went wrong while injecting "+depthmap+" into "+args[i]+".\nRemember: The first argument has to be a png and the following arguments must be jpgs shot with the blur function."); + System.out.println("Warning: Something went wrong while injecting "+depthmap+" into "+args[i]+".\nRemember: The first argument has to be a png and the following arguments must be jpgs shot with the blur function."); image.save(); } } @@ -73,9 +79,9 @@ public class DepthMapNeedle { JPEG image = new JPEG(args[i], wrapper); if (image.injectSourceImage(source)) - System.out.println("Source image injected into file "+args[i]+"."); + System.out.println("Info: Source image injected into file "+args[i]+"."); else - System.err.println("Something went wrong while injecting "+source+" into "+args[i]+".\nRemember: The first argument has to be a jpg and the following arguments must be jpgs shot with the blur function."); + System.out.println("Warning: Something went wrong while injecting "+source+" into "+args[i]+".\nRemember: The first argument has to be a jpg and the following arguments must be jpgs shot with the blur function."); image.save(); } } diff --git a/src/HexUtil.java b/src/HexUtil.java old mode 100644 new mode 100755 diff --git a/src/IO.java b/src/IO.java old mode 100644 new mode 100755 diff --git a/src/JPEG.java b/src/JPEG.java old mode 100644 new mode 100755 index eb7db8e..9e44b0e --- a/src/JPEG.java +++ b/src/JPEG.java @@ -1,5 +1,6 @@ import java.io.File; +import java.util.Arrays; public class JPEG extends Const { @@ -74,14 +75,19 @@ public class JPEG extends Const } /** - * extract the depth map from the jpeg and store it in the same location as the jpeg itself but with the suffix _d.png + * extract the depth map from the jpeg and store it in the same location as the jpeg itself + * but with the suffix '_d' and filetype suffix (jpg or png) * * @return */ public boolean exportDepthMap() { String out = m_Filename; - if (out.endsWith(".jpg") || out.endsWith(".JPG")) out = out.substring(0, out.length()-4); + if (out.endsWith(".jpg") || out.endsWith(".JPG")) + out = out.substring(0, out.length()-4); + String mime = extractDepthMapMIMEType(); + if(mime != null && mime.equals(Const.mimeJPG)) + return this.exportDepthMap(out+"_d.jpg"); return this.exportDepthMap(out+"_d.png"); } @@ -140,6 +146,14 @@ public class JPEG extends Const { return JPEGUtils.extractDepthMap(m_RawData); } + + public String extractDepthMapMIMEType() + { + byte[] mime = JPEGUtils.extract(m_RawData, Const.keyGDepthMIME); + if (mime != null) return new String(mime); + else + return null; + } /** * Extract and return the unblurred source image diff --git a/src/JPEGUtils.java b/src/JPEGUtils.java old mode 100644 new mode 100755 index b1523b9..3b49d3a --- a/src/JPEGUtils.java +++ b/src/JPEGUtils.java @@ -16,7 +16,7 @@ public class JPEGUtils extends Const //Check whether entered position is APP1 Marker if (!JPEGUtils.isAPP1Marker(data, boundaryPos)) { - System.err.println("JPEGUtils blockLength: Block is no APP1 Block!"); + System.err.println("JPEGUtils.blockLength(): Block is no APP1 Block!"); return -1; } int o; @@ -26,7 +26,7 @@ public class JPEGUtils extends Const o = 256 * (data[boundaryPos+2] & 0xFF)+(data[boundaryPos+3] & 0xFF); } catch (ArrayIndexOutOfBoundsException e) { - System.err.println("JPEGUtils blockLength threw ArrayIndexOutOfBoundsException. Maybe the block is cut after APP1 Marker?"); + System.err.println("JPEGUtils.blockLength() threw ArrayIndexOutOfBoundsException. Maybe the block is cut after APP1 Marker?"); e.printStackTrace(); return -1; } @@ -93,7 +93,7 @@ public class JPEGUtils extends Const out = ArrayUtils.concatenate(out, part); return out; } - System.err.println("JPEGUtils decorateBlock no valid type entered."); + System.err.println("JPEGUtils.decorateBlock(): No valid type entered."); return null; } @@ -124,10 +124,10 @@ public class JPEGUtils extends Const } } - System.err.println("JPEGUtils extract found end for \""+new String(key)+"\": false"); + System.err.println("JPEGUtils.extract() found end of key \""+new String(key)+"\": false"); } } - System.err.println("JPEGUtils extract found start for \""+new String(key)+"\": false"); + System.err.println("JPEGUtils.extract() found key \""+new String(key)+"\": false"); return null; } @@ -141,7 +141,7 @@ public class JPEGUtils extends Const { byte[] meta = getXMPBlocksContent(data); byte[] depth = extract(meta, keyGDepthData); - if (depth == null) System.err.println("JPEGUtils extractDepthMap is null"); + if (depth == null) System.err.println("JPEGUtils.extractDepthMap() is null!"); return depth; } @@ -155,7 +155,7 @@ public class JPEGUtils extends Const { byte[] meta = getXMPBlocksContent(data); byte[] src = extract(meta, keyGImageData); - if (src == null) System.err.println("JPEGUtils extractSourceImage is null"); + if (src == null) System.err.println("JPEGUtils.extractSourceImage() is null!"); return src; } @@ -184,7 +184,7 @@ public class JPEGUtils extends Const { if (!JPEGUtils.isAPP1Marker(data, boundary)) { - System.err.println("JPEGUtils getBlock: Block is no APP1-block"); + System.err.println("JPEGUtils.getBlock(): Block is no APP1-block!"); return data; } else { @@ -203,7 +203,7 @@ public class JPEGUtils extends Const { if (!JPEGUtils.isAPP1Marker(data, boundary)) { - System.err.println("JPEGUtils getBlockWithoutAPP1: Block is no APP1-block"); + System.err.println("JPEGUtils.getBlockWithoutAPP1(): Block is no APP1-block!"); return null; } else return Arrays.copyOfRange(data, boundary+4, boundary+JPEGUtils.readBlockLength(boundary, data)+2); @@ -221,7 +221,7 @@ public class JPEGUtils extends Const { if (!JPEGUtils.isAPP1Marker(data, boundary)) { - System.err.println("JPEGUtils getBlockWithoutHeader: Block is no APP1-block"); + System.err.println("JPEGUtils.getBlockWithoutHeader(): Block is no APP1-block!"); return null; } else { @@ -276,7 +276,7 @@ public class JPEGUtils extends Const byte[] block = getBlock(data, e); if (isEXIFBlock(block)) return getBlockWithoutHeader(data, e); } - System.err.println("JPEGUtils getEXIFBlock: No EXIF-block found"); + System.err.println("JPEGUtils.getEXIFBlock(): No EXIF-block found!"); return null; } @@ -297,7 +297,7 @@ public class JPEGUtils extends Const { byte[] part = JPEGUtils.getBlockWithoutHeader(block, 0); if (part == null) - System.err.println("JPEGUtils getExtendedXMPBlockContent part is null"); + System.err.println("JPEGUtils.getExtendedXMPBlockContent(): Part "+e+" is null!"); cont = ArrayUtils.concatenate(cont, part); } } @@ -355,7 +355,7 @@ public class JPEGUtils extends Const byte[] block = JPEGUtils.getBlock(data, e); if (JPEGUtils.isStandardXMP(block)) return JPEGUtils.getBlockWithoutHeader(data, e); } - System.err.println("JPEGUtils getStandardXMPBlockContent is null"); + System.err.println("JPEGUtils.getStandardXMPBlockContent() is null!"); return null; } @@ -371,7 +371,7 @@ public class JPEGUtils extends Const byte[] ext = getExtendedXMPBlockContent(data); byte[] out = ArrayUtils.concatenate(stand, ext); - if (out == null) System.err.println("JPEGUtils getXMPBlocksContent is null"); + if (out == null) System.err.println("JPEGUtils.getXMPBlocksContent() is null!"); return out; } @@ -503,8 +503,8 @@ public class JPEGUtils extends Const byte[] out = ArrayUtils.concatenate(pre, value); out = ArrayUtils.concatenate(out, post); return out; - } else System.err.println("JPEGUtils replace: No closing \" found in data"); - } else System.err.println("JPEGUtils replace: key not found in data"); + } else System.err.println("JPEGUtils.replace(): No closing \" found in data!"); + } else System.err.println("JPEGUtils.replace(): Key not found in data!"); return null; } }