Unverified Commit 0745140f authored by Aleksandr Veselov's avatar Aleksandr Veselov Committed by GitHub

Implement native Bitmap::peekPixels, add test (#306)

parent 8a392951
......@@ -975,17 +975,21 @@ class Bitmap internal constructor(ptr: NativePointer) : Managed(ptr, _FinalizerH
}
/**
* If pixel address is available, return ByteBuffer wrapping it.
* If pixel address is not available, return null.
* Create a pixmap and copy buffer contents into it
*
* @return ByteBuffer with direct access to pixels, or null
* @return Pixamp with copied pixels, or null
*
* @see [https://fiddle.skia.org/c/@Bitmap_peekPixels](https://fiddle.skia.org/c/@Bitmap_peekPixels)
*/
fun peekPixels(): ByteBuffer? {
fun peekPixels(): Pixmap? {
return try {
Stats.onNativeCall()
_nPeekPixels(_ptr)
val res = _nPeekPixels(_ptr)
if (res == NullPointer) {
null
} else {
Pixmap(res, true)
}
} finally {
reachabilityBarrier(this)
}
......@@ -1189,7 +1193,7 @@ private external fun _nReadPixels(
private external fun _nExtractAlpha(ptr: NativePointer, dstPtr: NativePointer, paintPtr: NativePointer, iPointResultIntArray: InteropPointer): Boolean
@ExternalSymbolName("org_jetbrains_skia_Bitmap__1nPeekPixels")
private external fun _nPeekPixels(ptr: NativePointer): ByteBuffer?
private external fun _nPeekPixels(ptr: NativePointer): NativePointer
@ExternalSymbolName("org_jetbrains_skia_Bitmap__1nMakeShader")
private external fun _nMakeShader(ptr: NativePointer, tmx: Int, tmy: Int, samplingMode: Long, localMatrix: InteropPointer): NativePointer
package org.jetbrains.skia
import org.jetbrains.skiko.KotlinBackend
import org.jetbrains.skiko.kotlinBackend
import org.jetbrains.skiko.tests.runTest
import kotlin.test.*
......@@ -68,6 +70,18 @@ class BitmapTest {
assertTrue(bitmap.rowBytes > 0)
assertEquals(5 * bitmap.rowBytes, result.size)
}
@Test
fun canPeekPixels() = runTest {
val bitmap = Bitmap()
bitmap.allocPixels(ImageInfo.makeS32(10, 10, ColorAlphaType.OPAQUE))
val result = bitmap.peekPixels()!!
assertEquals(10 * 4, result.rowBytes)
assertEquals(10 * 10 * 4, result.computeByteSize())
if (kotlinBackend == KotlinBackend.JVM) {
assertEquals(bitmap.imageInfo, result.info)
}
}
@Test //fixed bug https://github.com/JetBrains/skiko/pull/266
fun canReadPixelsWithGivenRowBytes() = runTest {
......
......@@ -259,14 +259,16 @@ extern "C" JNIEXPORT jboolean JNICALL Java_org_jetbrains_skia_BitmapKt__1nExtrac
return result;
}
extern "C" JNIEXPORT jobject JNICALL Java_org_jetbrains_skia_BitmapKt__1nPeekPixels
extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_BitmapKt__1nPeekPixels
(JNIEnv* env, jclass jclass, jlong ptr) {
SkBitmap* instance = reinterpret_cast<SkBitmap*>(static_cast<uintptr_t>(ptr));
SkPixmap pixmap;
if (instance->peekPixels(&pixmap))
return env->NewDirectByteBuffer(pixmap.writable_addr(), pixmap.rowBytes() * pixmap.height());
else
return nullptr;
SkPixmap* pixmap = new SkPixmap();
if (instance->peekPixels(pixmap))
return ptrToJlong(pixmap);
else {
delete pixmap;
return 0;
}
}
extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_BitmapKt__1nMakeShader
......
......@@ -19,31 +19,6 @@ private class DirectDataBuffer(val backing: ByteBuffer): DataBuffer(TYPE_BYTE, b
}
}
fun Bitmap.toBufferedImage(): BufferedImage {
val pixels = this.peekPixels()
val order = when (this.colorInfo.colorType) {
ColorType.RGB_888X -> intArrayOf(0, 1, 2, 3)
ColorType.BGRA_8888 -> intArrayOf(2, 1, 0, 3)
else -> throw UnsupportedOperationException("unsupported color type ${this.colorInfo.colorType}")
}
val raster = Raster.createInterleavedRaster(
DirectDataBuffer(pixels!!),
this.width,
this.height,
this.width * 4,
4,
order,
null
)
val colorModel = ComponentColorModel(
ColorSpace.getInstance(ColorSpace.CS_sRGB),
true,
false,
Transparency.TRANSLUCENT,
DataBuffer.TYPE_BYTE
)
return BufferedImage(colorModel, raster!!, false, null)
}
fun BufferedImage.toBitmap(): Bitmap {
val bytesPerPixel = 4
......
......@@ -279,7 +279,14 @@ SKIKO_EXPORT KBoolean org_jetbrains_skia_Bitmap__1nExtractAlpha
SKIKO_EXPORT KInteropPointer org_jetbrains_skia_Bitmap__1nPeekPixels
(KNativePointer ptr) {
TODO("implement org_jetbrains_skia_Bitmap__1nPeekPixels");
SkBitmap* instance = reinterpret_cast<SkBitmap*>(ptr);
SkPixmap* pixmap = new SkPixmap();
if (instance->peekPixels(pixmap)) {
return reinterpret_cast<KNativePointer>(pixmap);
} else {
delete pixmap;
return nullptr;
}
}
SKIKO_EXPORT KNativePointer org_jetbrains_skia_Bitmap__1nMakeShader
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment