Skip to content

Commit

Permalink
Adds overridable Bitmap.contentEquals and Bitmap.contentHashCode to a…
Browse files Browse the repository at this point in the history
…ll Bitmap implementations (#1730)
  • Loading branch information
soywiz authored Jun 28, 2023
1 parent 52fa935 commit 9b0a3f4
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 15 deletions.
17 changes: 12 additions & 5 deletions korim/src/commonMain/kotlin/korlibs/image/bitmap/Bitmap.kt
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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(
Expand Down Expand Up @@ -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) {
Expand All @@ -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)
Expand Down
7 changes: 5 additions & 2 deletions korim/src/commonMain/kotlin/korlibs/image/bitmap/Bitmap16.kt
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -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)"
}
4 changes: 2 additions & 2 deletions korim/src/commonMain/kotlin/korlibs/image/bitmap/Bitmap32.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
@@ -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(
Expand Down Expand Up @@ -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)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)"
}
Expand Down

0 comments on commit 9b0a3f4

Please sign in to comment.