import java.io.File; import java.util.Base64; public class JPEG extends Const { private String filename; private byte[] rawData; private byte[] exif; private byte[] xmpSta; private byte[] xmpExt; private byte[] tail; public JPEG(byte[] rawData) { this.init(rawData, null); } public JPEG(String filename) { this.init(IO.read(new File(filename)), filename); } public void disassemble() { exif = this.getEXIFBlock(); xmpSta = this.getStandardXMPBlockContent(); xmpExt = this.getExtendedXMPContent(); tail = this.getImageTail(); } public void exportDepthMap() { String out = filename; if(out.endsWith(".jpg") || out.endsWith(".JPG")) out = out.substring(0, out.length()-4); this.exportDepthMap(out+"_d.png"); } public void exportDepthMap(String file) { byte[] b64 = ArrayUtils.unsign(extractDepthMap()); byte[] depth = Base64.getDecoder().decode(b64); IO.write(depth, file); } public void exportSourceImage() { String out = filename; if(out.endsWith(".jpg") || out.endsWith(".JPG")) out = out.substring(0, out.length()-4); this.exportSourceImage(out+"_s.jpg"); } public void exportSourceImage(String file) { byte[] b64 = ArrayUtils.unsign(extractSourceImage()); byte[] src = Base64.getDecoder().decode(b64); IO.write(src, file); } public byte[] extractDepthMap() { return JPEGUtils.extractDepthMap(rawData); } public byte[] extractSourceImage() { return JPEGUtils.extractSourceImage(rawData); } public int[] getBoundaries() { return JPEGUtils.getBoundaries(rawData); } public byte[] getExif() { return exif; } public byte[] getEXIFBlock() { return JPEGUtils.getEXIFBlock(rawData); } public byte[] getExtendedXMPContent() { return JPEGUtils.getExtendedXMPBlockContent(rawData); } public String getFilename() { return filename; } public byte[] getImageTail() { return JPEGUtils.getImageTail(rawData); } public byte[] getMetadata() { return JPEGUtils.getMetadata(rawData); } public byte[] getRawData() { return this.rawData; } public byte[] getStandardXMPBlockContent() { return JPEGUtils.getStandardXMPBlockContent(rawData); } public byte[] getTail() { return tail; } public byte[] getXMPBlocksContent() { return JPEGUtils.getXMPBlocksContent(rawData); } public byte[] getXmpExt() { return xmpExt; } public byte[] getXmpSta() { return xmpSta; } private void init(byte[] raw, String filename) { this.rawData = raw; this.filename = filename; this.disassemble(); } public void injectDepthMap(String filename) { byte[] depth = Base64.getEncoder().encode(IO.read(new File(filename))); xmpExt = JPEGUtils.replace(xmpExt, keyGDepthData, depth); } public byte[] reassemble() { byte[] md5 = HexUtil.generateMD5(xmpExt); byte[] out = markJPG; out = ArrayUtils.concatenate(out, JPEGUtils.decorateBlock(exif,EXIF)); out = ArrayUtils.concatenate(out, JPEGUtils.decorateBlock(xmpSta, STANDARDXMP)); out = ArrayUtils.concatenate(out, JPEGUtils.decorateBlock(xmpExt, EXTENDEDXMP)); out = ArrayUtils.concatenate(out, tail); out = JPEGUtils.replace(out, keyHasExtendedXMP, md5); this.rawData = out; return out; } public void save() { this.save(filename); } public void save(String file) { IO.write(this.reassemble(), file); } public void setExif(byte[] exif) { this.exif=exif; } public void setTail(byte[] tail) { this.tail=tail; } public void setXmpExt(byte[] xmpExt) { this.xmpExt=xmpExt; } public void setXmpSta(byte[] xmpSta) { this.xmpSta=xmpSta; } }