package de.jeisfeld.augendiagnoselib.util.imagefile;
import java.util.Date;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import de.jeisfeld.augendiagnoselib.util.imagefile.EyePhoto.RightLeft;
/**
* Helper class holding the metadata to be written into the file.
*/
public final class JpegMetadata implements Parcelable {
/**
* Flag indicating that the overlay size has been set automatically by camera activity ant not by user.
*/
public static final int FLAG_OVERLAY_SET_BY_CAMERA_ACTIVITY = 0b10;
/**
* Flag indicating that the overlay size has been determined automatically by PupilAndIrisDetector.
*/
public static final int FLAG_OVERLAY_POSITION_DETERMINED_AUTOMATICALLY = 0b100;
// JAVADOC:OFF
private static final String LINE_BREAK = "\n";
@Nullable
private String mTitle = null;
@Nullable
private String mDescription = null;
@Nullable
private String mSubject = null;
@Nullable
private String mComment = null;
@Nullable
private String mPerson = null;
@Nullable
private Float mXCenter = null;
@Nullable
private Float mYCenter = null;
@Nullable
private Float mOverlayScaleFactor = null;
@Nullable
private Float mXPosition = null;
@Nullable
private Float mYPosition = null;
@Nullable
private Float mZoomFactor = null;
@Nullable
private Date mOrganizeDate = null;
@Nullable
private RightLeft mRightLeft = null;
@Nullable
private Float mBrightness = null;
@Nullable
private Float mContrast = null;
@Nullable
private Float mSaturation = null;
@Nullable
private Float mColorTemperature = null;
@Nullable
private Float mPupilSize = null;
@Nullable
private Float mPupilXOffset = null;
@Nullable
private Float mPupilYOffset = null;
@Nullable
private Integer mOverlayColor = null;
private int mFlags = 0;
@Nullable
public String getTitle() {
return mTitle;
}
public void setTitle(final String title) {
this.mTitle = title;
}
@Nullable
public String getDescription() {
return mDescription;
}
public void setDescription(final String description) {
this.mDescription = description;
}
@Nullable
public String getSubject() {
return mSubject;
}
public void setSubject(final String subject) {
this.mSubject = subject;
}
@Nullable
public String getComment() {
return mComment;
}
public void setComment(final String comment) {
this.mComment = comment;
}
@Nullable
public String getPerson() {
return mPerson;
}
public void setPerson(final String person) {
this.mPerson = person;
}
@Nullable
public Float getXCenter() {
return mXCenter;
}
public void setXCenter(final Float xCenter) {
this.mXCenter = xCenter;
}
@Nullable
public Float getYCenter() {
return mYCenter;
}
public void setYCenter(final Float yCenter) {
this.mYCenter = yCenter;
}
@Nullable
public Float getOverlayScaleFactor() {
return mOverlayScaleFactor;
}
public void setOverlayScaleFactor(final Float overlayScaleFactor) {
this.mOverlayScaleFactor = overlayScaleFactor;
}
@Nullable
public Float getXPosition() {
return mXPosition;
}
public void setXPosition(final Float xPosition) {
this.mXPosition = xPosition;
}
@Nullable
public Float getYPosition() {
return mYPosition;
}
public void setYPosition(final Float yPosition) {
this.mYPosition = yPosition;
}
@Nullable
public Float getZoomFactor() {
return mZoomFactor;
}
public void setZoomFactor(final Float zoomFactor) {
this.mZoomFactor = zoomFactor;
}
@Nullable
public Date getOrganizeDate() {
return mOrganizeDate;
}
public void setOrganizeDate(final Date organizeDate) {
this.mOrganizeDate = organizeDate;
}
@Nullable
public RightLeft getRightLeft() {
return mRightLeft;
}
public void setRightLeft(final RightLeft rightLeft) {
this.mRightLeft = rightLeft;
}
@Nullable
public Float getBrightness() {
return mBrightness;
}
public void setBrightness(final Float brightness) {
this.mBrightness = brightness;
}
@Nullable
public Float getContrast() {
return mContrast;
}
public void setContrast(final Float contrast) {
this.mContrast = contrast;
}
@Nullable
public Float getSaturation() {
return mSaturation;
}
public void setSaturation(final Float saturation) {
this.mSaturation = saturation;
}
@Nullable
public Float getColorTemperature() {
return mColorTemperature;
}
public void setColorTemperature(final Float colorTemparature) {
this.mColorTemperature = colorTemparature;
}
@Nullable
public Integer getOverlayColor() {
return mOverlayColor;
}
public void setOverlayColor(final Integer overlayColor) {
this.mOverlayColor = overlayColor;
}
@Nullable
public Float getPupilSize() {
return mPupilSize;
}
public void setPupilSize(final Float pupilSize) {
this.mPupilSize = pupilSize;
}
@Nullable
public Float getPupilXOffset() {
return mPupilXOffset;
}
public void setPupilXOffset(final Float pupilXOffset) {
this.mPupilXOffset = pupilXOffset;
}
@Nullable
public Float getPupilYOffset() {
return mPupilYOffset;
}
public void setPupilYOffset(final Float pupilYOffset) {
this.mPupilYOffset = pupilYOffset;
}
protected int getFlags() {
return mFlags;
}
protected void setFlags(final int flags) {
this.mFlags = flags;
}
/**
* The EXIF orientation is not persisted in the XMP Metadata structure, but only used for storage in EXIF.
*/
@Nullable
private Short mOrientation = null;
@Nullable
public Short getOrientation() {
return mOrientation;
}
public void setOrientation(final Short orientation) {
this.mOrientation = orientation;
}
// JAVADOC:ON
/**
* Check if overlay position is stored.
*
* @return true if overlay position is stored.
*/
public boolean hasOverlayPosition() {
return mXCenter != null && mYCenter != null && mOverlayScaleFactor != null;
}
/**
* Check if the position of the image in the view is stored.
*
* @return true if the image position is stored.
*/
public boolean hasViewPosition() {
return mXPosition != null && mYPosition != null && mZoomFactor != null;
}
/**
* Check if brightness and contrast are stored.
*
* @return true if brightness and contrast are stored.
*/
public boolean hasBrightnessContrast() {
return mBrightness != null && mContrast != null;
}
// JAVADOC:OFF
// Getters and setters with type conversion.
public void setXCenter(@Nullable final String value) {
mXCenter = value == null ? null : Float.parseFloat(value);
}
@Nullable
public String getXCenterString() {
return mXCenter == null ? null : mXCenter.toString();
}
public void setYCenter(@Nullable final String value) {
mYCenter = value == null ? null : Float.parseFloat(value);
}
@Nullable
public String getYCenterString() {
return mYCenter == null ? null : mYCenter.toString();
}
public void setOverlayScaleFactor(@Nullable final String value) {
mOverlayScaleFactor = value == null ? null : Float.parseFloat(value);
}
@Nullable
public String getOverlayScaleFactorString() {
return mOverlayScaleFactor == null ? null : mOverlayScaleFactor.toString();
}
public void setXPosition(@Nullable final String value) {
mXPosition = value == null ? null : Float.parseFloat(value);
}
@Nullable
public String getXPositionString() {
return mXPosition == null ? null : mXPosition.toString();
}
public void setYPosition(@Nullable final String value) {
mYPosition = value == null ? null : Float.parseFloat(value);
}
@Nullable
public String getYPositionString() {
return mYPosition == null ? null : mYPosition.toString();
}
public void setZoomFactor(@Nullable final String value) {
mZoomFactor = value == null ? null : Float.parseFloat(value);
}
@Nullable
public String getZoomFactorString() {
return mZoomFactor == null ? null : mZoomFactor.toString();
}
private long getOrganizeDateLong() {
return mOrganizeDate == null ? 0 : mOrganizeDate.getTime();
}
private void setOrganizeDateFromLong(final long timestamp) {
mOrganizeDate = timestamp == 0 ? null : new Date(timestamp);
}
public void setRightLeft(@Nullable final String value) {
mRightLeft = value == null ? null : RightLeft.fromString(value);
}
@Nullable
public String getRightLeftString() {
return mRightLeft == null ? null : mRightLeft.toString();
}
public void setBrightness(@Nullable final String value) {
mBrightness = value == null ? null : Float.parseFloat(value);
}
@Nullable
public String getBrightnessString() {
return mBrightness == null ? null : mBrightness.toString();
}
public void setContrast(@Nullable final String value) {
mContrast = value == null ? null : Float.parseFloat(value);
}
@Nullable
public String getContrastString() {
return mContrast == null ? null : mContrast.toString();
}
public void setSaturation(@Nullable final String value) {
mSaturation = value == null ? null : Float.parseFloat(value);
}
@Nullable
public String getSaturationString() {
return mSaturation == null ? null : mSaturation.toString();
}
public void setColorTemperature(@Nullable final String value) {
mColorTemperature = value == null ? null : Float.parseFloat(value);
}
@Nullable
public String getColorTemperatureString() {
return mColorTemperature == null ? null : mColorTemperature.toString();
}
public void setOverlayColor(@Nullable final String value) {
mOverlayColor = value == null ? null : (int) Long.parseLong(value, 16); // MAGIC_NUMBER
}
@Nullable
public String getOverlayColorString() {
return mOverlayColor == null ? null : Integer.toHexString(mOverlayColor);
}
public void setPupilSize(@Nullable final String value) {
mPupilSize = value == null ? null : Float.parseFloat(value);
}
@Nullable
public String getPupilSizeString() {
return mPupilSize == null ? null : mPupilSize.toString();
}
public void setPupilXOffset(@Nullable final String value) {
mPupilXOffset = value == null ? null : Float.parseFloat(value);
}
@Nullable
public String getPupilXOffsetString() {
return mPupilXOffset == null ? null : mPupilXOffset.toString();
}
public void setPupilYOffset(@Nullable final String value) {
mPupilYOffset = value == null ? null : Float.parseFloat(value);
}
@Nullable
public String getPupilYOffsetString() {
return mPupilYOffset == null ? null : mPupilYOffset.toString();
}
private void setOrientation(@Nullable final String value) {
mOrientation = value == null ? null : (short) Short.parseShort(value);
}
@Nullable
private String getOrientationString() {
return mOrientation == null ? null : Short.toString(mOrientation);
}
// JAVADOC:ON
/**
* Add a flag from the constants JpegMetadata.FLAG_XXX.
*
* @param flag The flag to be added.
*/
public void addFlag(final int flag) {
mFlags |= flag;
}
/**
* Remove a flag from the constants JpegMetadata.FLAG_XXX.
*
* @param flag The flag to be removed.
*/
public void removeFlag(final int flag) {
mFlags &= ~flag;
}
/**
* Get a flag from the constants JpegMetadata.FLAG_XXX.
*
* @param flag The flag to be retrieved.
* @return true if the flag is set.
*/
public boolean hasFlag(final int flag) {
return (mFlags & flag) != 0;
}
@Override
public String toString() {
StringBuilder str = new StringBuilder();
str.append("Title: ").append(mTitle).append(LINE_BREAK);
str.append("Description: ").append(mDescription).append(LINE_BREAK);
str.append("Subject: ").append(mSubject).append(LINE_BREAK);
str.append("Comment: ").append(mComment).append(LINE_BREAK);
str.append("Person: ").append(mPerson).append(LINE_BREAK);
str.append("X-Center: ").append(mXCenter).append(LINE_BREAK);
str.append("Y-Center: ").append(mYCenter).append(LINE_BREAK);
str.append("OverlayScaleFactor: ").append(mOverlayScaleFactor).append(LINE_BREAK);
str.append("X-Position: ").append(mXPosition).append(LINE_BREAK);
str.append("Y-Position: ").append(mYPosition).append(LINE_BREAK);
str.append("ZoomFactor: ").append(mZoomFactor).append(LINE_BREAK);
str.append("OrganizeDate: ").append(mOrganizeDate).append(LINE_BREAK);
str.append("RightLeft: ").append(mRightLeft).append(LINE_BREAK);
str.append("Brightness: ").append(mBrightness).append(LINE_BREAK);
str.append("RightLeft: ").append(mRightLeft).append(LINE_BREAK);
str.append("Brightness: ").append(mBrightness).append(LINE_BREAK);
str.append("Contrast: ").append(mContrast).append(LINE_BREAK);
str.append("Saturation: ").append(mSaturation).append(LINE_BREAK);
str.append("ColorTemperature: ").append(mColorTemperature).append(LINE_BREAK);
str.append("OverlayColor: ").append(getOverlayColorString()).append(LINE_BREAK);
str.append("Pupil-Size: ").append(mPupilSize).append(LINE_BREAK);
str.append("Pupil-X-Offset: ").append(mPupilXOffset).append(LINE_BREAK);
str.append("Pupil-Y-Offset: ").append(mPupilYOffset).append(LINE_BREAK);
str.append("Flags: ").append(mFlags).append(LINE_BREAK);
str.append("Orientation: ").append(getOrientationString()).append(LINE_BREAK);
return str.toString();
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(@NonNull final Parcel dest, final int flags) {
// using String values in order to be fine with null values
dest.writeString(mTitle);
dest.writeString(mDescription);
dest.writeString(mSubject);
dest.writeString(mComment);
dest.writeString(mPerson);
dest.writeString(getXCenterString());
dest.writeString(getYCenterString());
dest.writeString(getOverlayScaleFactorString());
dest.writeLong(getOrganizeDateLong());
dest.writeString(getRightLeftString());
dest.writeString(getBrightnessString());
dest.writeString(getContrastString());
dest.writeString(getSaturationString());
dest.writeString(getColorTemperatureString());
dest.writeString(getOverlayColorString());
dest.writeString(getPupilSizeString());
dest.writeString(getPupilXOffsetString());
dest.writeString(getPupilYOffsetString());
dest.writeInt(mFlags);
dest.writeString(getOrientationString());
}
/**
* Required field for Parcelable implementation.
*/
public static final Parcelable.Creator<JpegMetadata> CREATOR = new Parcelable.Creator<JpegMetadata>() {
@NonNull
@Override
public JpegMetadata createFromParcel(@NonNull final Parcel in) {
JpegMetadata metadata = new JpegMetadata();
metadata.mTitle = in.readString();
metadata.mDescription = in.readString();
metadata.mSubject = in.readString();
metadata.mComment = in.readString();
metadata.mPerson = in.readString();
metadata.setXCenter(in.readString());
metadata.setYCenter(in.readString());
metadata.setOverlayScaleFactor(in.readString());
metadata.setOrganizeDateFromLong(in.readLong());
metadata.setRightLeft(in.readString());
metadata.setBrightness(in.readString());
metadata.setContrast(in.readString());
metadata.setSaturation(in.readString());
metadata.setColorTemperature(in.readString());
metadata.setOverlayColor(in.readString());
metadata.setPupilSize(in.readString());
metadata.setPupilXOffset(in.readString());
metadata.setPupilYOffset(in.readString());
metadata.mFlags = in.readInt();
metadata.setOrientation(in.readString());
return metadata;
}
@NonNull
@Override
public JpegMetadata[] newArray(final int size) {
return new JpegMetadata[size];
}
};
}