mirror of
https://github.com/vanitasvitae/Spherical
synced 2024-11-22 12:22:08 +01:00
Clean up code
This commit is contained in:
parent
e6e0b1f680
commit
179d3b7bd2
2 changed files with 67 additions and 88 deletions
|
@ -3,44 +3,42 @@ package de.trac.spherical.parser;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by vanitas on 12.09.17.
|
* XMP Metadata of a PhotoSphere image.
|
||||||
|
* @see <a href="https://developers.google.com/streetview/spherical-metadata">documentation</a>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class PhotoSphereMetadata {
|
public class PhotoSphereMetadata {
|
||||||
|
|
||||||
public static final String USE_PANORAMA_VIEWER = "GPano:UsePanoramaViewer";
|
static final String USE_PANORAMA_VIEWER = "GPano:UsePanoramaViewer";
|
||||||
public static final String CAPTURE_SOFTWARE = "GPano:CaptureSoftware";
|
static final String CAPTURE_SOFTWARE = "GPano:CaptureSoftware";
|
||||||
public static final String STITCHING_SOFTWARE = "GPano:StitchingSoftware";
|
static final String STITCHING_SOFTWARE = "GPano:StitchingSoftware";
|
||||||
public static final String PROJECTION_TYPE = "GPano:ProjectionType";
|
static final String PROJECTION_TYPE = "GPano:ProjectionType";
|
||||||
public static final String POSE_HEADING_DEGREES = "GPano:PoseHeadingDegrees";
|
static final String POSE_HEADING_DEGREES = "GPano:PoseHeadingDegrees";
|
||||||
public static final String POSE_PITCH_DEGREES = "GPano:PosePitchDegrees";
|
static final String POSE_PITCH_DEGREES = "GPano:PosePitchDegrees";
|
||||||
public static final String POSE_ROLL_DEGREES = "GPano:PoseRollDegrees";
|
static final String POSE_ROLL_DEGREES = "GPano:PoseRollDegrees";
|
||||||
public static final String INITIAL_VIEW_HEADING_DEGREES = "GPano:InitialViewHeadingDegrees";
|
static final String INITIAL_VIEW_HEADING_DEGREES = "GPano:InitialViewHeadingDegrees";
|
||||||
public static final String INITIAL_VIEW_PITCH_DEGREES = "GPano:InitialViewPitchDegrees";
|
static final String INITIAL_VIEW_PITCH_DEGREES = "GPano:InitialViewPitchDegrees";
|
||||||
public static final String INITIAL_VIEW_ROLL_DEGREES = "GPano:InitialViewRollDegrees";
|
static final String INITIAL_VIEW_ROLL_DEGREES = "GPano:InitialViewRollDegrees";
|
||||||
public static final String INITIAL_HORIZONTAL_POV_DEGREES = "GPano:InitialHorizontalFOVDegrees";
|
static final String INITIAL_HORIZONTAL_POV_DEGREES = "GPano:InitialHorizontalFOVDegrees";
|
||||||
public static final String FIRST_PHOTO_DATE = "GPano:FirstPhotoDate";
|
static final String FIRST_PHOTO_DATE = "GPano:FirstPhotoDate";
|
||||||
public static final String LAST_PHOTO_DATE = "GPano:LastPhotoDate";
|
static final String LAST_PHOTO_DATE = "GPano:LastPhotoDate";
|
||||||
public static final String SOURCE_PHOTOS_COUNT = "GPano:SourcePhotosCount";
|
static final String SOURCE_PHOTOS_COUNT = "GPano:SourcePhotosCount";
|
||||||
public static final String EXPOSURE_LOCK_USED = "GPano:ExposureLockUsed";
|
static final String EXPOSURE_LOCK_USED = "GPano:ExposureLockUsed";
|
||||||
public static final String CROPPED_AREA_IMAGE_WIDTH_PIXELS = "GPano:CroppedAreaImageWidthPixels";
|
static final String CROPPED_AREA_IMAGE_WIDTH_PIXELS = "GPano:CroppedAreaImageWidthPixels";
|
||||||
public static final String CROPPED_AREA_IMAGE_HEIGHT_PIXELS = "GPano:CroppedAreaImageHeightPixels";
|
static final String CROPPED_AREA_IMAGE_HEIGHT_PIXELS = "GPano:CroppedAreaImageHeightPixels";
|
||||||
public static final String FULL_PANO_WIDTH_PIXELS = "GPano:FullPanoWidthPixels";
|
static final String FULL_PANO_WIDTH_PIXELS = "GPano:FullPanoWidthPixels";
|
||||||
public static final String FULL_PANO_HEIGHT_PIXELS = "GPano:FullPanoHeightPixels";
|
static final String FULL_PANO_HEIGHT_PIXELS = "GPano:FullPanoHeightPixels";
|
||||||
public static final String CROPPED_AREA_LEFT_PIXELS = "GPano:CroppedAreaLeftPixels";
|
static final String CROPPED_AREA_LEFT_PIXELS = "GPano:CroppedAreaLeftPixels";
|
||||||
public static final String CROPPED_AREA_TOP_PIXELS = "GPano:CroppedAreaTopPixels";
|
static final String CROPPED_AREA_TOP_PIXELS = "GPano:CroppedAreaTopPixels";
|
||||||
public static final String INITIAL_CAMERA_DOLLY = "GPano:InitialCameraDolly";
|
static final String INITIAL_CAMERA_DOLLY = "GPano:InitialCameraDolly";
|
||||||
|
|
||||||
private static final String pf = "=\"";
|
enum ProjectionType {
|
||||||
|
|
||||||
enum TYPE {
|
|
||||||
equirectangular
|
equirectangular
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean usePanoramaViewer = true;
|
private boolean usePanoramaViewer = true;
|
||||||
private String captureSoftware = null;
|
private String captureSoftware = null;
|
||||||
private String stitichingSoftware = null;
|
private String stitchingSoftware = null;
|
||||||
private TYPE projectionType = TYPE.equirectangular;
|
private ProjectionType projectionType = ProjectionType.equirectangular;
|
||||||
private Float poseHeadingDegrees = null;
|
private Float poseHeadingDegrees = null;
|
||||||
private float posePitchDegrees = 0;
|
private float posePitchDegrees = 0;
|
||||||
private float poseRollDegrees = 0;
|
private float poseRollDegrees = 0;
|
||||||
|
@ -68,11 +66,11 @@ public class PhotoSphereMetadata {
|
||||||
this.captureSoftware = captureSoftware;
|
this.captureSoftware = captureSoftware;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setStitichingSoftware(String stitichingSoftware) {
|
public void setStitchingSoftware(String stitchingSoftware) {
|
||||||
this.stitichingSoftware = stitichingSoftware;
|
this.stitchingSoftware = stitchingSoftware;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setProjectionType(TYPE projectionType) {
|
public void setProjectionType(ProjectionType projectionType) {
|
||||||
this.projectionType = projectionType;
|
this.projectionType = projectionType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,7 +147,6 @@ public class PhotoSphereMetadata {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isUsePanoramaViewer() {
|
public boolean isUsePanoramaViewer() {
|
||||||
|
|
||||||
return usePanoramaViewer;
|
return usePanoramaViewer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,11 +154,11 @@ public class PhotoSphereMetadata {
|
||||||
return captureSoftware;
|
return captureSoftware;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getStitichingSoftware() {
|
public String getStitchingSoftware() {
|
||||||
return stitichingSoftware;
|
return stitchingSoftware;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TYPE getProjectionType() {
|
public ProjectionType getProjectionType() {
|
||||||
return projectionType;
|
return projectionType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,15 +3,11 @@ package de.trac.spherical.parser;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import java.io.EOFException;
|
import java.io.EOFException;
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.PushbackInputStream;
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
@ -37,7 +33,7 @@ import static de.trac.spherical.parser.PhotoSphereMetadata.POSE_ROLL_DEGREES;
|
||||||
import static de.trac.spherical.parser.PhotoSphereMetadata.PROJECTION_TYPE;
|
import static de.trac.spherical.parser.PhotoSphereMetadata.PROJECTION_TYPE;
|
||||||
import static de.trac.spherical.parser.PhotoSphereMetadata.SOURCE_PHOTOS_COUNT;
|
import static de.trac.spherical.parser.PhotoSphereMetadata.SOURCE_PHOTOS_COUNT;
|
||||||
import static de.trac.spherical.parser.PhotoSphereMetadata.STITCHING_SOFTWARE;
|
import static de.trac.spherical.parser.PhotoSphereMetadata.STITCHING_SOFTWARE;
|
||||||
import static de.trac.spherical.parser.PhotoSphereMetadata.TYPE;
|
import static de.trac.spherical.parser.PhotoSphereMetadata.ProjectionType;
|
||||||
import static de.trac.spherical.parser.PhotoSphereMetadata.USE_PANORAMA_VIEWER;
|
import static de.trac.spherical.parser.PhotoSphereMetadata.USE_PANORAMA_VIEWER;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -45,7 +41,7 @@ import static de.trac.spherical.parser.PhotoSphereMetadata.USE_PANORAMA_VIEWER;
|
||||||
*/
|
*/
|
||||||
public class SphereParser {
|
public class SphereParser {
|
||||||
|
|
||||||
public static final String TAG = "SphereParser";
|
private static final String TAG = "PhoSphePars";
|
||||||
|
|
||||||
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SSS'Z'", Locale.US);
|
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SSS'Z'", Locale.US);
|
||||||
|
|
||||||
|
@ -56,23 +52,23 @@ public class SphereParser {
|
||||||
* 3 E1
|
* 3 E1
|
||||||
* 4 Length EXIF (n)
|
* 4 Length EXIF (n)
|
||||||
* 5 Length EXIF (n)
|
* 5 Length EXIF (n)
|
||||||
* 6 <exif>
|
* 6 <exif> (length n-2)
|
||||||
* n+4 </exif>
|
* n+4 </exif>
|
||||||
* n+5 FF
|
* n+5 FF
|
||||||
* n+6 E1
|
* n+6 E1
|
||||||
* n+7 Length XML (m)
|
* n+7 Length XML (m)
|
||||||
* n+7 Length XML (m)
|
* n+7 Length XML (m)
|
||||||
* n+8 <xml>
|
* n+8 <xml> (length m-2)
|
||||||
* n+8+m</xml>
|
* n+8+m</xml>
|
||||||
* n+5 <xml>
|
* n+5 <xml>
|
||||||
* ? </xml>
|
* ? </xml>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public static final byte[] FFE1 = new byte[] {
|
private static final byte[] FFE1 = new byte[] {
|
||||||
(byte) 0xFF, (byte) 0xE1
|
(byte) 0xFF, (byte) 0xE1
|
||||||
};
|
};
|
||||||
|
|
||||||
public static final byte[] FFD8FFE1 = new byte[] {
|
private static final byte[] FFD8FFE1 = new byte[] {
|
||||||
(byte) 0xFF, (byte) 0xD8, (byte) 0xFF, (byte) 0xE1
|
(byte) 0xFF, (byte) 0xD8, (byte) 0xFF, (byte) 0xE1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -86,7 +82,8 @@ public class SphereParser {
|
||||||
//HEADER
|
//HEADER
|
||||||
byte[] r = new byte[FFD8FFE1.length];
|
byte[] r = new byte[FFD8FFE1.length];
|
||||||
int i = inputStream.read(r);
|
int i = inputStream.read(r);
|
||||||
if (i != FFD8FFE1.length || !Arrays.equals(FFD8FFE1, r)) {
|
throwIfUnexpectedEOF(i, r.length);
|
||||||
|
if (!Arrays.equals(FFD8FFE1, r)) {
|
||||||
Log.d(TAG, "Unexpected Image header: " + hex(r) + " (" + hex(FFD8FFE1) + " expected)");
|
Log.d(TAG, "Unexpected Image header: " + hex(r) + " (" + hex(FFD8FFE1) + " expected)");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -94,18 +91,18 @@ public class SphereParser {
|
||||||
//EXIF Length
|
//EXIF Length
|
||||||
r = new byte[2];
|
r = new byte[2];
|
||||||
i = inputStream.read(r);
|
i = inputStream.read(r);
|
||||||
if (i != 2) {
|
throwIfUnexpectedEOF(i, r.length);
|
||||||
throw new EOFException("Unexpected EOF!");
|
|
||||||
}
|
|
||||||
int exifLen = integer(r);
|
int exifLen = integer(r);
|
||||||
|
|
||||||
//Skip EXIF header
|
//Skip EXIF header
|
||||||
r = new byte[exifLen - 2];
|
r = new byte[exifLen - 2];
|
||||||
i = inputStream.read(r);
|
i = inputStream.read(r);
|
||||||
|
throwIfUnexpectedEOF(i, r.length);
|
||||||
|
|
||||||
//XML Header
|
//XML Header
|
||||||
r = new byte[2];
|
r = new byte[2];
|
||||||
i = inputStream.read(r);
|
i = inputStream.read(r);
|
||||||
|
throwIfUnexpectedEOF(i, r.length);
|
||||||
if (!Arrays.equals(FFE1, r)) {
|
if (!Arrays.equals(FFE1, r)) {
|
||||||
Log.d(TAG, "Image does not contain XML data.");
|
Log.d(TAG, "Image does not contain XML data.");
|
||||||
return null;
|
return null;
|
||||||
|
@ -113,16 +110,12 @@ public class SphereParser {
|
||||||
|
|
||||||
r = new byte[2];
|
r = new byte[2];
|
||||||
i = inputStream.read(r);
|
i = inputStream.read(r);
|
||||||
if (i != 2) {
|
throwIfUnexpectedEOF(i, r.length);
|
||||||
throw new EOFException("Unexpected EOF!");
|
|
||||||
}
|
|
||||||
int xmlLen = integer(r);
|
int xmlLen = integer(r);
|
||||||
|
|
||||||
byte[] xml = new byte[xmlLen - 2];
|
byte[] xml = new byte[xmlLen - 2];
|
||||||
i = inputStream.read(xml);
|
i = inputStream.read(xml);
|
||||||
if (i != xml.length) {
|
throwIfUnexpectedEOF(i, r.length);
|
||||||
throw new EOFException("Unexpected EOF!");
|
|
||||||
}
|
|
||||||
|
|
||||||
return new String(xml);
|
return new String(xml);
|
||||||
}
|
}
|
||||||
|
@ -130,9 +123,9 @@ public class SphereParser {
|
||||||
public static PhotoSphereMetadata parse(String xmp) {
|
public static PhotoSphereMetadata parse(String xmp) {
|
||||||
PhotoSphereMetadata meta = new PhotoSphereMetadata();
|
PhotoSphereMetadata meta = new PhotoSphereMetadata();
|
||||||
meta.setUsePanoramaViewer(parseBoolean(USE_PANORAMA_VIEWER, xmp, true));
|
meta.setUsePanoramaViewer(parseBoolean(USE_PANORAMA_VIEWER, xmp, true));
|
||||||
meta.setCaptureSoftware(getStringValue(CAPTURE_SOFTWARE, xmp));
|
meta.setCaptureSoftware(parseString(CAPTURE_SOFTWARE, xmp));
|
||||||
meta.setStitichingSoftware(getStringValue(STITCHING_SOFTWARE, xmp));
|
meta.setStitchingSoftware(parseString(STITCHING_SOFTWARE, xmp));
|
||||||
meta.setProjectionType(parseType(PROJECTION_TYPE, xmp, TYPE.equirectangular));
|
meta.setProjectionType(parseType(PROJECTION_TYPE, xmp, ProjectionType.equirectangular));
|
||||||
meta.setPoseHeadingDegrees(parseFloat(POSE_HEADING_DEGREES, xmp, null));
|
meta.setPoseHeadingDegrees(parseFloat(POSE_HEADING_DEGREES, xmp, null));
|
||||||
meta.setPosePitchDegrees(parseFloat(POSE_PITCH_DEGREES, xmp, 0f));
|
meta.setPosePitchDegrees(parseFloat(POSE_PITCH_DEGREES, xmp, 0f));
|
||||||
meta.setPoseRollDegrees(parseFloat(POSE_ROLL_DEGREES, xmp, 0f));
|
meta.setPoseRollDegrees(parseFloat(POSE_ROLL_DEGREES, xmp, 0f));
|
||||||
|
@ -154,7 +147,13 @@ public class SphereParser {
|
||||||
return meta;
|
return meta;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getStringValue(String key, String xmp) {
|
private static void throwIfUnexpectedEOF(int actual, int expected) throws EOFException {
|
||||||
|
if (actual != expected) {
|
||||||
|
throw new EOFException("Unexpected EOF!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String parseString(String key, String xmp) {
|
||||||
if (!xmp.contains(key)) {
|
if (!xmp.contains(key)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -165,13 +164,13 @@ public class SphereParser {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Integer parseInteger(String key, String xmp, Integer defaultValue) {
|
private static Integer parseInteger(String key, String xmp, Integer defaultValue) {
|
||||||
String value = getStringValue(key, xmp);
|
String value = parseString(key, xmp);
|
||||||
return value == null ? defaultValue : Integer.parseInt(value);
|
return value == null ? defaultValue : Integer.parseInt(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Float parseFloat(String key, String xmp, Float defaultValue) {
|
private static Float parseFloat(String key, String xmp, Float defaultValue) {
|
||||||
String value = getStringValue(key, xmp);
|
String value = parseString(key, xmp);
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
} else {
|
} else {
|
||||||
|
@ -179,18 +178,18 @@ public class SphereParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Boolean parseBoolean(String key, String xmp, Boolean defaultValue) {
|
private static Boolean parseBoolean(String key, String xmp, Boolean defaultValue) {
|
||||||
String value = getStringValue(key, xmp);
|
String value = parseString(key, xmp);
|
||||||
return value == null ? defaultValue : Boolean.parseBoolean(value);
|
return value == null ? defaultValue : Boolean.parseBoolean(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TYPE parseType(String key, String xmp, TYPE defaultValue) {
|
private static ProjectionType parseType(String key, String xmp, ProjectionType defaultValue) {
|
||||||
String value = getStringValue(key, xmp);
|
String value = parseString(key, xmp);
|
||||||
return value == null ? defaultValue : TYPE.equirectangular;
|
return value == null ? defaultValue : ProjectionType.equirectangular;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Date parseDate(String key, String xmp, Date defaultValue) {
|
private static Date parseDate(String key, String xmp, Date defaultValue) {
|
||||||
String value = getStringValue(key, xmp);
|
String value = parseString(key, xmp);
|
||||||
try {
|
try {
|
||||||
return value == null ? defaultValue : dateFormat.parse(value);
|
return value == null ? defaultValue : dateFormat.parse(value);
|
||||||
} catch (ParseException e) {
|
} catch (ParseException e) {
|
||||||
|
@ -198,23 +197,6 @@ public class SphereParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
|
||||||
File file = new File(args[0]);
|
|
||||||
System.out.println(getXMLContent(new FileInputStream(file)));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void unread(ArrayList<Byte> list, PushbackInputStream pb) throws IOException {
|
|
||||||
for (int i = list.size() - 1; i >= 0; i--) {
|
|
||||||
pb.unread(list.get(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void append(ArrayList<Byte> list, byte[] array, int r) {
|
|
||||||
for (int i = 0; i < r; i++) {
|
|
||||||
list.add(array[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String hex(byte[] b) {
|
private static String hex(byte[] b) {
|
||||||
return new BigInteger(b).toString(16);
|
return new BigInteger(b).toString(16);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue