Skip to content

Commit d709bbb

Browse files
authored
Fix bindings for PixelRef (#1149)
This PR fixes https://youtrack.jetbrains.com/issue/SKIKO-996 The PixelRef bindings have two mistakes in them: 1. `rowBytes` is defined as a `NativePointer`, whereas it is actually an integer with the number of bytes per row. This is the same as `Bitmap::rowBytes`. 2. It is missing the `pixels` property that actually returns a pointer to the pixel data. See: https://api.skia.org/classSkPixelRef.html
1 parent d6e53c5 commit d709bbb

File tree

8 files changed

+81
-3
lines changed

8 files changed

+81
-3
lines changed

skiko/src/commonMain/kotlin/org/jetbrains/skia/PixelRef.kt

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,20 @@ class PixelRef internal constructor(ptr: NativePointer) : RefCnt(ptr) {
2727
} finally {
2828
reachabilityBarrier(this)
2929
}
30-
val rowBytes: NativePointer
30+
val rowBytes: Int
3131
get() = try {
3232
Stats.onNativeCall()
3333
PixelRef_nGetRowBytes(_ptr)
3434
} finally {
3535
reachabilityBarrier(this)
3636
}
37+
val pixels: NativePointer
38+
get() = try {
39+
Stats.onNativeCall()
40+
PixelRef_nGetPixels(_ptr)
41+
} finally {
42+
reachabilityBarrier(this)
43+
}
3744

3845
/**
3946
* Returns a non-zero, unique value corresponding to the pixels in this
@@ -83,8 +90,11 @@ class PixelRef internal constructor(ptr: NativePointer) : RefCnt(ptr) {
8390
}
8491
}
8592

93+
@ExternalSymbolName("org_jetbrains_skia_PixelRef__1nGetPixels")
94+
private external fun PixelRef_nGetPixels(ptr: NativePointer): NativePointer
95+
8696
@ExternalSymbolName("org_jetbrains_skia_PixelRef__1nGetRowBytes")
87-
private external fun PixelRef_nGetRowBytes(ptr: NativePointer): NativePointer
97+
private external fun PixelRef_nGetRowBytes(ptr: NativePointer): Int
8898

8999
@ExternalSymbolName("org_jetbrains_skia_PixelRef__1nGetGenerationId")
90100
private external fun PixelRef_nGetGenerationId(ptr: NativePointer): Int
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package org.jetbrains.skia
2+
3+
import org.jetbrains.skia.util.assertIsNotNullPointer
4+
import kotlin.test.Test
5+
import kotlin.test.assertEquals
6+
import kotlin.test.assertNotNull
7+
8+
class PixelRefTest {
9+
10+
@Test
11+
fun pixelRefTest() {
12+
val bitmap = Bitmap()
13+
bitmap.allocPixels(ImageInfo.makeS32(7, 3, ColorAlphaType.OPAQUE))
14+
15+
val pixelRef = bitmap.pixelRef
16+
assertNotNull(pixelRef)
17+
assertEquals(7, pixelRef.width)
18+
assertEquals(3, pixelRef.height)
19+
assertEquals(7 * 4, pixelRef.rowBytes)
20+
assertIsNotNullPointer(pixelRef.pixels)
21+
}
22+
23+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package org.jetbrains.skia.util
2+
3+
import org.jetbrains.skia.impl.NativePointer
4+
import kotlin.test.assertFalse
5+
import kotlin.test.assertTrue
6+
7+
internal expect val NativePointer.isNullPointer: Boolean
8+
9+
fun assertIsNullPointer(ptr: NativePointer) =
10+
assertTrue(ptr.isNullPointer, message = "Expected a null pointer")
11+
12+
fun assertIsNotNullPointer(ptr: NativePointer) =
13+
assertFalse(ptr.isNullPointer, message = "Expected a non-null pointer")

skiko/src/jvmMain/cpp/common/PixelRef.cc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,13 @@ extern "C" JNIEXPORT jint JNICALL Java_org_jetbrains_skia_PixelRefKt__1nGetHeigh
1414
return instance->height();
1515
}
1616

17-
extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_PixelRefKt_PixelRef_1nGetRowBytes
17+
extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_PixelRefKt_PixelRef_1nGetPixels
18+
(JNIEnv* env, jclass jclass, jlong ptr) {
19+
SkPixelRef* instance = reinterpret_cast<SkPixelRef*>(static_cast<uintptr_t>(ptr));
20+
return reinterpret_cast<jlong>(instance->pixels());
21+
}
22+
23+
extern "C" JNIEXPORT jint JNICALL Java_org_jetbrains_skia_PixelRefKt_PixelRef_1nGetRowBytes
1824
(JNIEnv* env, jclass jclass, jlong ptr) {
1925
SkPixelRef* instance = reinterpret_cast<SkPixelRef*>(static_cast<uintptr_t>(ptr));
2026
return instance->rowBytes();
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package org.jetbrains.skia.util
2+
3+
import org.jetbrains.skia.impl.NativePointer
4+
5+
internal actual val NativePointer.isNullPointer: Boolean
6+
get() = this == 0L

skiko/src/nativeJsMain/cpp/PixelRef.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ SKIKO_EXPORT KInt org_jetbrains_skia_PixelRef__1nGetHeight
1313
return instance->height();
1414
}
1515

16+
SKIKO_EXPORT KNativePointer org_jetbrains_skia_PixelRef__1nGetPixels
17+
(KNativePointer ptr) {
18+
SkPixelRef* instance = reinterpret_cast<SkPixelRef*>((ptr));
19+
return instance->pixels();
20+
}
21+
1622
SKIKO_EXPORT KInt org_jetbrains_skia_PixelRef__1nGetRowBytes
1723
(KNativePointer ptr) {
1824
SkPixelRef* instance = reinterpret_cast<SkPixelRef*>((ptr));
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package org.jetbrains.skia.util
2+
3+
import kotlinx.cinterop.ExperimentalForeignApi
4+
import org.jetbrains.skia.impl.NativePointer
5+
6+
@OptIn(ExperimentalForeignApi::class)
7+
internal actual val NativePointer.isNullPointer: Boolean
8+
get() = this == NativePointer.NULL
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package org.jetbrains.skia.util
2+
3+
import org.jetbrains.skia.impl.NativePointer
4+
5+
internal actual val NativePointer.isNullPointer: Boolean
6+
get() = this == 0

0 commit comments

Comments
 (0)