zcash-android-wallet-zcon1/zcash-android-wallet-app/qrecycler/src/main/java/cash/z/android/cameraview/base/AspectRatio.kt

174 lines
5.1 KiB
Kotlin

/*
* Copyright (C) 2019 Electric Coin Company
*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* This file has been modified by Electric Coin Company to translate it into Kotlin and add support for Firebase vision.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cash.z.android.cameraview.base
import android.os.Parcel
import android.os.Parcelable
import androidx.annotation.NonNull
import androidx.collection.SparseArrayCompat
/**
* Immutable class for describing proportional relationship between width and height.
*/
class AspectRatio private constructor(val x: Int, val y: Int) : Comparable<AspectRatio>, Parcelable {
constructor(parcel: Parcel) : this(
parcel.readInt(),
parcel.readInt()
) {
}
fun matches(size: Size): Boolean {
val gcd = gcd(size.width, size.height)
val x = size.width / gcd
val y = size.height / gcd
return this.x == x && this.y == y
}
override fun equals(o: Any?): Boolean {
if (o == null) {
return false
}
if (this === o) {
return true
}
if (o is AspectRatio) {
val ratio = o as AspectRatio?
return x == ratio!!.x && y == ratio.y
}
return false
}
override fun toString(): String {
return x.toString() + ":" + y
}
fun toFloat(): Float {
return x.toFloat() / y
}
override fun hashCode(): Int {
// assuming most sizes are <2^16, doing a rotate will give us perfect hashing
return y xor (x shl Integer.SIZE / 2 or x.ushr(Integer.SIZE / 2))
}
override fun compareTo(@NonNull another: AspectRatio): Int {
if (equals(another)) {
return 0
} else if (toFloat() - another.toFloat() > 0) {
return 1
}
return -1
}
/**
* @return The inverse of this [AspectRatio].
*/
fun inverse(): AspectRatio {
return AspectRatio.of(y, x)
}
override fun describeContents(): Int {
return 0
}
override fun writeToParcel(dest: Parcel, flags: Int) {
dest.writeInt(x)
dest.writeInt(y)
}
companion object CREATOR : Parcelable.Creator<AspectRatio> {
private val sCache = SparseArrayCompat<SparseArrayCompat<AspectRatio>>(16)
/**
* Returns an instance of [AspectRatio] specified by `x` and `y` values.
* The values `x` and `` will be reduced by their greatest common divider.
*
* @param x The width
* @param y The height
* @return An instance of [AspectRatio]
*/
fun of(inX: Int, inY: Int): AspectRatio {
var x = inX
var y = inY
val gcd = gcd(x, y)
x /= gcd
y /= gcd
var arrayX: SparseArrayCompat<AspectRatio>? = sCache.get(x)
if (arrayX == null) {
val ratio = AspectRatio(x, y)
arrayX = SparseArrayCompat()
arrayX!!.put(y, ratio)
sCache.put(x, arrayX)
return ratio
} else {
var ratio = arrayX!!.get(y)
if (ratio == null) {
ratio = AspectRatio(x, y)
arrayX!!.put(y, ratio)
}
return ratio
}
}
/**
* Parse an [AspectRatio] from a [String] formatted like "4:3".
*
* @param s The string representation of the aspect ratio
* @return The aspect ratio
* @throws IllegalArgumentException when the format is incorrect.
*/
fun parse(s: String): AspectRatio {
val position = s.indexOf(':')
if (position == -1) {
throw IllegalArgumentException("Malformed aspect ratio: $s")
}
try {
val x = Integer.parseInt(s.substring(0, position))
val y = Integer.parseInt(s.substring(position + 1))
return AspectRatio.of(x, y)
} catch (e: NumberFormatException) {
throw IllegalArgumentException("Malformed aspect ratio: $s", e)
}
}
private fun gcd(a: Int, b: Int): Int {
var a = a
var b = b
while (b != 0) {
val c = b
b = a % b
a = c
}
return a
}
override fun createFromParcel(parcel: Parcel): AspectRatio {
return AspectRatio(parcel)
}
override fun newArray(size: Int): Array<AspectRatio?> {
return arrayOfNulls(size)
}
}
}