diff --git a/korim/src/commonMain/kotlin/korlibs/image/bitmap/Bitmap.kt b/korim/src/commonMain/kotlin/korlibs/image/bitmap/Bitmap.kt index 7e2b1cfefd..8e3c4378cb 100644 --- a/korim/src/commonMain/kotlin/korlibs/image/bitmap/Bitmap.kt +++ b/korim/src/commonMain/kotlin/korlibs/image/bitmap/Bitmap.kt @@ -1,10 +1,6 @@ package korlibs.image.bitmap import korlibs.datastructure.* -import korlibs.memory.clamp -import korlibs.memory.fract -import korlibs.memory.toIntCeil -import korlibs.memory.toIntFloor import korlibs.image.color.Colors import korlibs.image.color.RGBA import korlibs.image.color.RGBAPremultiplied @@ -16,6 +12,7 @@ import korlibs.image.vector.Context2d import korlibs.io.lang.invalidOp import korlibs.math.geom.* import korlibs.math.interpolation.* +import korlibs.memory.* import kotlin.math.min abstract class Bitmap( @@ -286,7 +283,7 @@ abstract class Bitmap( fun toBMP32IfRequired(): Bitmap32 = if (this is Bitmap32) this else this.toBMP32() - fun contentEquals(other: Bitmap): Boolean { + open fun contentEquals(other: Bitmap): Boolean { if (this.width != other.width) return false if (this.height != other.height) return false for (y in 0 until height) for (x in 0 until width) { @@ -295,6 +292,16 @@ abstract class Bitmap( return true } + open fun contentHashCode(): Int { + var v = 0 + for (y in 0 until height) { + for (x in 0 until width) { + v += this.getRgbaRaw(x, y).value.hashCode() * (7 + x + y * 3) + } + } + return (width * 31 + height) + v + premultiplied.toInt() + } + open fun clone(): Bitmap { val out = createWithThisFormat(width, height) copyUnchecked(0, 0, out, 0, 0, width, height) diff --git a/korim/src/commonMain/kotlin/korlibs/image/bitmap/Bitmap16.kt b/korim/src/commonMain/kotlin/korlibs/image/bitmap/Bitmap16.kt index 1194502aa6..de9a1e2f62 100644 --- a/korim/src/commonMain/kotlin/korlibs/image/bitmap/Bitmap16.kt +++ b/korim/src/commonMain/kotlin/korlibs/image/bitmap/Bitmap16.kt @@ -1,12 +1,12 @@ package korlibs.image.bitmap -import korlibs.memory.arraycopy import korlibs.image.color.ColorFormat import korlibs.image.color.RGBA import korlibs.image.color.RGBA_4444 import korlibs.image.color.packRGBA import korlibs.image.color.unpackToRGBA import korlibs.io.lang.assert +import korlibs.memory.* class Bitmap16( width: Int, @@ -42,5 +42,8 @@ class Bitmap16( } } - override fun toString(): String = "Bitmap16($width, $height, format=$format)" + override fun contentEquals(other: Bitmap): Boolean = (other is Bitmap16) && (this.width == other.width) && (this.height == other.height) && data.contentEquals(other.data) + override fun contentHashCode(): Int = (width * 31 + height) + data.contentHashCode() + premultiplied.toInt() + + override fun toString(): String = "Bitmap16($width, $height, format=$format)" } diff --git a/korim/src/commonMain/kotlin/korlibs/image/bitmap/Bitmap32.kt b/korim/src/commonMain/kotlin/korlibs/image/bitmap/Bitmap32.kt index a40760538d..d6d92efbe8 100644 --- a/korim/src/commonMain/kotlin/korlibs/image/bitmap/Bitmap32.kt +++ b/korim/src/commonMain/kotlin/korlibs/image/bitmap/Bitmap32.kt @@ -389,8 +389,8 @@ class Bitmap32( fun yCbCrToRgba(): Bitmap32 = clone().apply { yCbCrToRgbaInline() } fun yCbCrToRgbaInline() = updateColors { YCbCr(it.value).toRGBA() } - fun contentEquals(other: Any?): Boolean = (other is Bitmap32) && (this.width == other.width) && (this.height == other.height) && ints.contentEquals(other.ints) - fun contentHashCode(): Int = (width * 31 + height) + ints.contentHashCode() + premultiplied.toInt() + override fun contentEquals(other: Bitmap): Boolean = (other is Bitmap32) && (this.width == other.width) && (this.height == other.height) && ints.contentEquals(other.ints) + override fun contentHashCode(): Int = (width * 31 + height) + ints.contentHashCode() + premultiplied.toInt() // @TODO: Can't do this or won't be able to put Bitmaps on hashmaps //override fun equals(other: Any?): Boolean = (other is Bitmap32) && (this.width == other.width) && (this.height == other.height) && data.ints.contentEquals(other.data.ints) diff --git a/korim/src/commonMain/kotlin/korlibs/image/bitmap/BitmapIndexed.kt b/korim/src/commonMain/kotlin/korlibs/image/bitmap/BitmapIndexed.kt index 428eb18a39..2cd0d48306 100644 --- a/korim/src/commonMain/kotlin/korlibs/image/bitmap/BitmapIndexed.kt +++ b/korim/src/commonMain/kotlin/korlibs/image/bitmap/BitmapIndexed.kt @@ -1,12 +1,8 @@ package korlibs.image.bitmap -import korlibs.memory.UByteArrayInt -import korlibs.memory.arraycopy -import korlibs.memory.extract -import korlibs.memory.ilog2 -import korlibs.memory.insert import korlibs.image.color.RGBA import korlibs.image.color.RgbaArray +import korlibs.memory.* import kotlin.math.max abstract class BitmapIndexed( @@ -103,7 +99,10 @@ abstract class BitmapIndexed( return maxRefColor + 1 } - override fun toBMP32(): Bitmap32 = Bitmap32(width, height, premultiplied = premultiplied).also { outBmp -> + override fun contentEquals(other: Bitmap): Boolean = (other is BitmapIndexed) && (this.width == other.width) && (this.height == other.height) && data.contentEquals(other.data) + override fun contentHashCode(): Int = (width * 31 + height) + data.contentHashCode() + premultiplied.toInt() + + override fun toBMP32(): Bitmap32 = Bitmap32(width, height, premultiplied = premultiplied).also { outBmp -> val out = outBmp.ints val pal = this@BitmapIndexed.palette.ints for (n in 0 until area) out[n] = pal[getIntIndex(n)] diff --git a/korim/src/commonMain/kotlin/korlibs/image/bitmap/FloatBitmap32.kt b/korim/src/commonMain/kotlin/korlibs/image/bitmap/FloatBitmap32.kt index fd02ac95cf..ae4c62573b 100644 --- a/korim/src/commonMain/kotlin/korlibs/image/bitmap/FloatBitmap32.kt +++ b/korim/src/commonMain/kotlin/korlibs/image/bitmap/FloatBitmap32.kt @@ -122,6 +122,9 @@ class FloatBitmap32( } } + override fun contentEquals(other: Bitmap): Boolean = (other is FloatBitmap32) && (this.width == other.width) && (this.height == other.height) && data.contentEquals(other.data) + override fun contentHashCode(): Int = (width * 31 + height) + data.contentHashCode() + premultiplied.toInt() + inline fun updateComponent(block: (component: Int, value: Float) -> Float): Unit { forEach { n, x, y -> setRgbaf( diff --git a/korim/src/commonMain/kotlin/korlibs/image/bitmap/NativeImage.kt b/korim/src/commonMain/kotlin/korlibs/image/bitmap/NativeImage.kt index 1c72e32edb..615c8f2aab 100644 --- a/korim/src/commonMain/kotlin/korlibs/image/bitmap/NativeImage.kt +++ b/korim/src/commonMain/kotlin/korlibs/image/bitmap/NativeImage.kt @@ -61,6 +61,9 @@ abstract class NativeImage(width: Int, height: Int, val data: Any?, premultiplie writePixelsUnsafe(x0, 0, 1, height, tempInts, width) } + override fun contentEquals(other: Bitmap): Boolean = toBMP32().contentEquals(other) + override fun contentHashCode(): Int = toBMP32().contentHashCode() + override fun createWithThisFormat(width: Int, height: Int): Bitmap = NativeImage(width, height) override fun toString(): String = "$name($width, $height)" }