package com.flurgle.camerakit; import android.os.Parcel; import android.os.Parcelable; import android.support.annotation.NonNull; import android.support.v4.util.SparseArrayCompat; public class AspectRatio implements Comparable<AspectRatio>, Parcelable { private final static SparseArrayCompat<SparseArrayCompat<AspectRatio>> sCache = new SparseArrayCompat<>(16); private final int mX; private final int mY; private AspectRatio(int x, int y) { mX = x; mY = y; } public int getX() { return mX; } public int getY() { return mY; } public boolean matches(Size size) { int gcd = gcd(size.getWidth(), size.getHeight()); int x = size.getWidth() / gcd; int y = size.getHeight() / gcd; return mX == x && mY == y; } @Override public boolean equals(Object o) { if (o == null) { return false; } if (this == o) { return true; } if (o instanceof AspectRatio) { AspectRatio ratio = (AspectRatio) o; return mX == ratio.mX && mY == ratio.mY; } return false; } @Override public String toString() { return mX + ":" + mY; } public float toFloat() { return (float) mX / mY; } @Override public int hashCode() { return mY ^ ((mX << (Integer.SIZE / 2)) | (mX >>> (Integer.SIZE / 2))); } @Override public int compareTo(@NonNull AspectRatio another) { if (equals(another)) { return 0; } else if (toFloat() - another.toFloat() > 0) { return 1; } return -1; } public AspectRatio inverse() { return AspectRatio.of(mY, mX); } public static AspectRatio of(int x, int y) { int gcd = gcd(x, y); x /= gcd; y /= gcd; SparseArrayCompat<AspectRatio> arrayX = sCache.get(x); if (arrayX == null) { AspectRatio ratio = new AspectRatio(x, y); arrayX = new SparseArrayCompat<>(); arrayX.put(y, ratio); sCache.put(x, arrayX); return ratio; } else { AspectRatio ratio = arrayX.get(y); if (ratio == null) { ratio = new AspectRatio(x, y); arrayX.put(y, ratio); } return ratio; } } private static int gcd(int a, int b) { while (b != 0) { int c = b; b = a % b; a = c; } return a; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(mX); dest.writeInt(mY); } public static final Parcelable.Creator<AspectRatio> CREATOR = new Parcelable.Creator<AspectRatio>() { @Override public AspectRatio createFromParcel(Parcel source) { int x = source.readInt(); int y = source.readInt(); return AspectRatio.of(x, y); } @Override public AspectRatio[] newArray(int size) { return new AspectRatio[size]; } }; }