Unverified Commit b1dfd1ce authored by Oleksandr Karpovich's avatar Oleksandr Karpovich Committed by GitHub

Commonize BitmapTest.kt (#248)

* commonize BitmapTest.kt

* commonize BitmapTest.kt: refactor org_jetbrains_skia_Bitmap__1nGetImageInfo

* commonize BitmapTest.kt: org_jetbrains_skia_Bitmap__1nReadPixels org_jetbrains_skia_Bitmap__1nExtractAlpha org_jetbrains_skia_Bitmap__1nMakeShader

* commonize BitmapTest.kt: fix for CI-found issue

* BitmapTest fixes

* refactor Bitmap.cc

* add `canInstallPixels` to BitmapTest.kt

* refactor org_jetbrains_skia_Bitmap__1nGetImageInfo: remove unnecessary casts
Co-authored-by: 's avatarOleksandr Karpovich <oleksandr.karpovich@jetbrains.com>
parent 27a93c41
......@@ -35,9 +35,18 @@ SKIKO_EXPORT void org_jetbrains_skia_Bitmap__1nSwap
}
SKIKO_EXPORT KInteropPointer org_jetbrains_skia_Bitmap__1nGetImageInfo
(KNativePointer ptr) {
TODO("implement org_jetbrains_skia_Bitmap__1nGetImageInfo");
SKIKO_EXPORT void org_jetbrains_skia_Bitmap__1nGetImageInfo
(KNativePointer ptr, KInt* imageInfoResult, KNativePointer* colorSpacePtrsArray) {
SkBitmap* instance = reinterpret_cast<SkBitmap*>(ptr);
SkImageInfo imageInfo = instance->info();
imageInfoResult[0] = instance->width();
imageInfoResult[1] = instance->height();
imageInfoResult[2] = static_cast<int>(imageInfo.colorType());
imageInfoResult[3] = static_cast<int>(imageInfo.alphaType());
colorSpacePtrsArray[0] = imageInfo.refColorSpace().release();
}
#if 0
......@@ -141,28 +150,16 @@ SKIKO_EXPORT KBoolean org_jetbrains_skia_Bitmap__1nAllocPixelsRowBytes
SKIKO_EXPORT KBoolean org_jetbrains_skia_Bitmap__1nInstallPixels
(KNativePointer ptr, KInt width, KInt height, KInt colorType, KInt alphaType, KNativePointer colorSpacePtr, KByte* pixelsArr, KNativePointer rowBytes) {
TODO("implement org_jetbrains_skia_Bitmap__1nInstallPixels");
}
#if 0
SKIKO_EXPORT KBoolean org_jetbrains_skia_Bitmap__1nInstallPixels
(KNativePointer ptr, KInt width, KInt height, KInt colorType, KInt alphaType, KNativePointer colorSpacePtr, KByte* pixelsArr, KNativePointer rowBytes) {
SkBitmap* instance = reinterpret_cast<SkBitmap*>((ptr));
SkColorSpace* colorSpace = reinterpret_cast<SkColorSpace*>((colorSpacePtr));
(KNativePointer ptr, KInt width, KInt height, KInt colorType, KInt alphaType, KNativePointer colorSpacePtr, KByte* pixelsArr, KInt rowBytes) {
SkBitmap* instance = reinterpret_cast<SkBitmap*>(ptr);
SkColorSpace* colorSpace = reinterpret_cast<SkColorSpace*>(colorSpacePtr);
SkImageInfo imageInfo = SkImageInfo::Make(width,
height,
static_cast<SkColorType>(colorType),
static_cast<SkAlphaType>(alphaType),
sk_ref_sp<SkColorSpace>(colorSpace));
jsize len = env->GetArrayLength(pixelsArr);
KByte* pixels = new KByte[len];
env->GetByteArrayRegion(pixelsArr, 0, len, pixels);
return instance->installPixels(imageInfo, pixels, rowBytes, deleteJBytes, nullptr);
return instance->installPixels(imageInfo, pixelsArr, rowBytes, nullptr, nullptr);
}
#endif
SKIKO_EXPORT KBoolean org_jetbrains_skia_Bitmap__1nAllocPixels
(KNativePointer ptr) {
......@@ -242,32 +239,41 @@ SKIKO_EXPORT KBoolean org_jetbrains_skia_Bitmap__1nExtractSubset
}
SKIKO_EXPORT KByte* org_jetbrains_skia_Bitmap__1nReadPixels
(KNativePointer ptr, KInt width, KInt height, KInt colorType, KInt alphaType, KNativePointer colorSpacePtr, KNativePointer rowBytes, KInt srcX, KInt srcY) {
TODO("implement org_jetbrains_skia_Bitmap__1nReadPixels");
}
#if 0
SKIKO_EXPORT KByte* org_jetbrains_skia_Bitmap__1nReadPixels
(KNativePointer ptr, KInt width, KInt height, KInt colorType, KInt alphaType, KNativePointer colorSpacePtr, KNativePointer rowBytes, KInt srcX, KInt srcY) {
SkBitmap* instance = reinterpret_cast<SkBitmap*>((ptr));
SkColorSpace* colorSpace = reinterpret_cast<SkColorSpace*>((colorSpacePtr));
// returns true if readBytes array contains successfully read bytes. returns false otherwise
SKIKO_EXPORT KBoolean org_jetbrains_skia_Bitmap__1nReadPixels
(KNativePointer ptr, KInt width, KInt height, KInt colorType,
KInt alphaType, KNativePointer colorSpacePtr, KInt rowBytes, KInt srcX, KInt srcY, KByte* resultBytes
) {
SkBitmap* instance = reinterpret_cast<SkBitmap*>(ptr);
SkColorSpace* colorSpace = reinterpret_cast<SkColorSpace*>(colorSpacePtr);
SkImageInfo imageInfo = SkImageInfo::Make(width,
height,
static_cast<SkColorType>(colorType),
static_cast<SkAlphaType>(alphaType),
sk_ref_sp<SkColorSpace>(colorSpace));
std::vector<KByte> pixels(std::min(height, instance->height() - srcY) * rowBytes);
if (instance->readPixels(imageInfo, pixels.data(), rowBytes, srcX, srcY))
return javaByteArray(env, pixels);
else
return nullptr;
if (instance->readPixels(imageInfo, resultBytes, rowBytes, srcX, srcY)) {
return true;
} else {
return false;
}
}
#endif
SKIKO_EXPORT KInteropPointer org_jetbrains_skia_Bitmap__1nExtractAlpha
(KNativePointer ptr, KNativePointer dstPtr, KNativePointer paintPtr) {
TODO("implement org_jetbrains_skia_Bitmap__1nExtractAlpha");
SKIKO_EXPORT KBoolean org_jetbrains_skia_Bitmap__1nExtractAlpha
(KNativePointer ptr, KNativePointer dstPtr, KNativePointer paintPtr, KInt* result) {
SkBitmap* instance = reinterpret_cast<SkBitmap*>(ptr);
SkBitmap* dst = reinterpret_cast<SkBitmap*>(dstPtr);
SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
SkIPoint offset;
if (instance->extractAlpha(dst, paint, &offset)) {
result[0] = offset.fX;
result[1] = offset.fY;
return true;
} else {
return false;
}
}
SKIKO_EXPORT KInteropPointer org_jetbrains_skia_Bitmap__1nPeekPixels
......@@ -276,7 +282,15 @@ SKIKO_EXPORT KInteropPointer org_jetbrains_skia_Bitmap__1nPeekPixels
}
SKIKO_EXPORT KNativePointer org_jetbrains_skia_Bitmap__1nMakeShader
(KNativePointer ptr, KInt tmx, KInt tmy, KNativePointer samplingMode, KFloat* localMatrixArr) {
TODO("implement org_jetbrains_skia_Bitmap__1nMakeShader");
(KNativePointer ptr, KInt tmx, KInt tmy, KLong samplingMode, KFloat* localMatrixArr) {
SkBitmap* instance = reinterpret_cast<SkBitmap*>(ptr);
std::unique_ptr<SkMatrix> localMatrix = skMatrix(localMatrixArr);
sk_sp<SkShader> shader = instance->makeShader(
static_cast<SkTileMode>(tmx),
static_cast<SkTileMode>(tmy),
skija::SamplingMode::unpack(samplingMode),
localMatrix.get()
);
return reinterpret_cast<KNativePointer>(shader.release());
}
......@@ -2,6 +2,7 @@ package org.jetbrains.skia
import org.jetbrains.skia.impl.*
import org.jetbrains.skia.impl.Library.Companion.staticLoad
import kotlin.math.min
class Bitmap internal constructor(ptr: NativePointer) : Managed(ptr, _FinalizerHolder.PTR), IHasImageInfo {
companion object {
......@@ -70,7 +71,21 @@ class Bitmap internal constructor(ptr: NativePointer) : Managed(ptr, _FinalizerH
get() = try {
if (_imageInfo == null) {
Stats.onNativeCall()
_imageInfo = _nGetImageInfo(_ptr)
var colorSpacePtr: NativePointer? = null
_imageInfo = withResult(IntArray(4)) { intArrayPointer ->
colorSpacePtr = withResult(NativePointerArray(1)) { nativePointerArrayPtr ->
_nGetImageInfo(_ptr, intArrayPointer, nativePointerArrayPtr)
}[0]
}.let {
ImageInfo(
width = it[0],
height = it[1],
colorType = it[2],
alphaType = it[3],
colorSpace = colorSpacePtr!!
)
}
}
_imageInfo!!
} finally {
......@@ -126,7 +141,7 @@ class Bitmap internal constructor(ptr: NativePointer) : Managed(ptr, _FinalizerH
*
* @return byte length of pixel row
*/
val rowBytes: Long
val rowBytes: Int
get() = try {
Stats.onNativeCall()
_nGetRowBytes(_ptr)
......@@ -371,7 +386,7 @@ class Bitmap internal constructor(ptr: NativePointer) : Managed(ptr, _FinalizerH
*
* @see [https://fiddle.skia.org/c/@Bitmap_setInfo](https://fiddle.skia.org/c/@Bitmap_setInfo)
*/
fun setImageInfo(imageInfo: ImageInfo, rowBytes: Long): Boolean {
fun setImageInfo(imageInfo: ImageInfo, rowBytes: Int): Boolean {
return try {
_imageInfo = null
Stats.onNativeCall()
......@@ -448,7 +463,7 @@ class Bitmap internal constructor(ptr: NativePointer) : Managed(ptr, _FinalizerH
* @param rowBytes size of pixel row or larger; may be zero
* @return true if pixel storage is allocated
*/
fun allocPixels(info: ImageInfo, rowBytes: Long): Boolean {
fun allocPixels(info: ImageInfo, rowBytes: Int): Boolean {
return try {
_imageInfo = null
Stats.onNativeCall()
......@@ -554,7 +569,7 @@ class Bitmap internal constructor(ptr: NativePointer) : Managed(ptr, _FinalizerH
fun installPixels(
info: ImageInfo,
pixels: ByteArray?,
rowBytes: Long
rowBytes: Int
): Boolean {
return try {
_imageInfo = null
......@@ -896,12 +911,15 @@ class Bitmap internal constructor(ptr: NativePointer) : Managed(ptr, _FinalizerH
*/
fun readPixels(
dstInfo: ImageInfo = imageInfo,
dstRowBytes: Long = rowBytes,
dstRowBytes: Int = rowBytes,
srcX: Int = 0,
srcY: Int = 0
): ByteArray? {
return try {
val size = min(dstInfo.height, height - srcY) * rowBytes
Stats.onNativeCall()
withNullableResult(ByteArray(size)) {
_nReadPixels(
_ptr,
dstInfo.width,
......@@ -911,8 +929,10 @@ class Bitmap internal constructor(ptr: NativePointer) : Managed(ptr, _FinalizerH
getPtr(dstInfo.colorInfo.colorSpace),
dstRowBytes,
srcX,
srcY
srcY,
it
)
}
} finally {
reachabilityBarrier(this)
reachabilityBarrier(dstInfo.colorInfo.colorSpace)
......@@ -948,11 +968,16 @@ class Bitmap internal constructor(ptr: NativePointer) : Managed(ptr, _FinalizerH
fun extractAlpha(dst: Bitmap, paint: Paint?): IPoint? {
return try {
Stats.onNativeCall()
withNullableResult(IntArray(2)) {
_nExtractAlpha(
_ptr,
getPtr(dst),
getPtr(paint)
ptr = _ptr,
dstPtr = getPtr(dst),
paintPtr = getPtr(paint),
iPointResultIntArray = it
)
}?.let {
IPoint(x = it[0], y = it[1])
}
} finally {
reachabilityBarrier(this)
reachabilityBarrier(dst)
......@@ -1035,7 +1060,7 @@ private external fun _nSwap(ptr: NativePointer, otherPtr: NativePointer)
private external fun _nGetPixmap(ptr: NativePointer): NativePointer
@ExternalSymbolName("org_jetbrains_skia_Bitmap__1nGetImageInfo")
private external fun _nGetImageInfo(ptr: NativePointer): ImageInfo?
private external fun _nGetImageInfo(ptr: NativePointer, imageInfo: InteropPointer, colorSpacePtrs: InteropPointer)
@ExternalSymbolName("org_jetbrains_skia_Bitmap__1nGetRowBytesAsPixels")
private external fun _nGetRowBytesAsPixels(ptr: NativePointer): Int
......@@ -1044,7 +1069,7 @@ private external fun _nGetRowBytesAsPixels(ptr: NativePointer): Int
private external fun _nIsNull(ptr: NativePointer): Boolean
@ExternalSymbolName("org_jetbrains_skia_Bitmap__1nGetRowBytes")
private external fun _nGetRowBytes(ptr: NativePointer): Long
private external fun _nGetRowBytes(ptr: NativePointer): Int
@ExternalSymbolName("org_jetbrains_skia_Bitmap__1nSetAlphaType")
private external fun _nSetAlphaType(ptr: NativePointer, alphaType: Int): Boolean
......@@ -1078,7 +1103,7 @@ private external fun _nSetImageInfo(
colorType: Int,
alphaType: Int,
colorSpacePtr: NativePointer,
rowBytes: Long
rowBytes: Int
): Boolean
......@@ -1102,7 +1127,7 @@ private external fun _nAllocPixelsRowBytes(
colorType: Int,
alphaType: Int,
colorSpacePtr: NativePointer,
rowBytes: Long
rowBytes: Int
): Boolean
......@@ -1115,7 +1140,7 @@ private external fun _nInstallPixels(
alphaType: Int,
colorSpacePtr: NativePointer,
pixels: InteropPointer,
rowBytes: Long
rowBytes: Int
): Boolean
......@@ -1163,14 +1188,15 @@ private external fun _nReadPixels(
colorType: Int,
alphaType: Int,
colorSpacePtr: NativePointer,
dstRowBytes: Long,
dstRowBytes: Int,
srcX: Int,
srcY: Int
): ByteArray?
srcY: Int,
resultBytes: InteropPointer
): Boolean
@ExternalSymbolName("org_jetbrains_skia_Bitmap__1nExtractAlpha")
private external fun _nExtractAlpha(ptr: NativePointer, dstPtr: NativePointer, paintPtr: NativePointer): IPoint?
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?
......
......@@ -48,8 +48,8 @@ class ImageInfo(val colorInfo: ColorInfo, val width: Int, val height: Int) {
* specifies getBytesPerPixel(). Bitmap maximum value for row bytes must fit
* in 31 bits.
*/
val minRowBytes: Long
get() = (width * bytesPerPixel).toLong()
val minRowBytes: Int
get() = (width * bytesPerPixel)
val colorType: ColorType
get() = colorInfo.colorType
......@@ -172,7 +172,7 @@ class ImageInfo(val colorInfo: ColorInfo, val width: Int, val height: Int) {
*
* @see [https://fiddle.skia.org/c/@ImageInfo_computeByteSize](https://fiddle.skia.org/c/@ImageInfo_computeByteSize)
*/
fun computeByteSize(rowBytes: Long): Long {
fun computeByteSize(rowBytes: Int): Int {
return if (0 == height) 0 else (height - 1) * rowBytes + width * bytesPerPixel
}
......@@ -185,7 +185,7 @@ class ImageInfo(val colorInfo: ColorInfo, val width: Int, val height: Int) {
*
* @return least memory required by pixel buffer
*/
fun computeMinByteSize(): Long {
fun computeMinByteSize(): Int {
return computeByteSize(minRowBytes)
}
......
......@@ -51,6 +51,16 @@ inline fun withResult(result: ByteArray, block: (InteropPointer) -> Unit): ByteA
result
}
inline fun withNullableResult(result: ByteArray, block: (InteropPointer) -> Boolean): ByteArray? = interopScope {
val handle = toInterop(result)
return if (block(handle)) {
handle.fromInterop(result)
result
} else {
null
}
}
inline fun withResult(result: FloatArray, block: (InteropPointer) -> Unit): FloatArray = interopScope {
val handle = toInterop(result)
block(handle)
......@@ -65,6 +75,16 @@ inline fun withResult(result: IntArray, block: (InteropPointer) -> Unit): IntArr
result
}
inline fun withNullableResult(result: IntArray, block: (InteropPointer) -> Boolean): IntArray? = interopScope {
val handle = toInterop(result)
return if (block(handle)) {
handle.fromInterop(result)
result
} else {
null
}
}
inline fun withResult(result: ShortArray, block: (InteropPointer) -> Unit): ShortArray = interopScope {
val handle = toInterop(result)
block(handle)
......
package org.jetbrains.skiko
package org.jetbrains.skia
import org.jetbrains.skia.Bitmap
import org.jetbrains.skia.ColorAlphaType
import org.jetbrains.skia.ImageInfo
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertNotEquals
import kotlin.test.assertTrue
import org.jetbrains.skiko.tests.runTest
import kotlin.test.*
class BitmapTest {
@Test
fun bitmapTest() {
fun bitmapTest() = runTest {
val bitmap = Bitmap()
val id1: Int = bitmap.generationId
......@@ -23,19 +17,22 @@ class BitmapTest {
assertNotEquals(id1, bitmap.generationId)
assertFalse(bitmap.isNull)
assertFalse(bitmap.isEmpty)
assertEquals(7L * 4, bitmap.rowBytes)
assertEquals(7 * 4, bitmap.rowBytes)
assertEquals(4, bitmap.bytesPerPixel)
assertEquals(7, bitmap.rowBytesAsPixels)
assertTrue(bitmap.imageInfo.colorSpace!!.isSRGB)
bitmap.allocPixels(ImageInfo.makeS32(7, 3, ColorAlphaType.OPAQUE), 32)
assertEquals(32L, bitmap.rowBytes)
assertEquals(32, bitmap.rowBytes)
assertEquals(4, bitmap.bytesPerPixel)
assertEquals(8, bitmap.rowBytesAsPixels)
assertTrue(bitmap.imageInfo.colorSpace!!.isSRGB)
bitmap.setImageInfo(ImageInfo.makeS32(7, 3, ColorAlphaType.OPAQUE))
assertTrue(bitmap.isNull)
assertFalse(bitmap.isEmpty)
assertFalse(bitmap.isReadyToDraw)
assertTrue(bitmap.imageInfo.colorSpace!!.isSRGB)
bitmap.allocPixels()
assertFalse(bitmap.isNull)
......@@ -43,4 +40,46 @@ class BitmapTest {
bitmap.generationId
}
@Test
fun canMakeShader() = runTest {
val bitmap = Bitmap()
bitmap.allocPixels(ImageInfo.makeS32(25, 25, ColorAlphaType.OPAQUE))
val shader = bitmap.makeShader(Matrix33.makeRotate(45f))
}
@Test
fun canExtractAlpha() = runTest {
val bitmap = Bitmap()
bitmap.allocPixels(ImageInfo.makeS32(25, 25, ColorAlphaType.OPAQUE))
val bitmap2 = Bitmap()
bitmap2.allocPixels(ImageInfo.makeS32(15, 15, ColorAlphaType.OPAQUE))
assertTrue(bitmap.extractAlpha(bitmap2))
}
@Test
fun canReadPixels() = runTest {
val bitmap = Bitmap()
bitmap.allocPixels(ImageInfo.makeS32(10, 10, ColorAlphaType.OPAQUE))
val result = bitmap.readPixels(srcY = 5)!!
assertTrue(bitmap.rowBytes > 0)
assertEquals(5 * bitmap.rowBytes, result.size)
}
@Test
fun canInstallPixels() = runTest {
val bitmap = Bitmap()
bitmap.allocPixels(ImageInfo.makeS32(2, 2, ColorAlphaType.OPAQUE))
val setArray = byteArrayOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)
assertTrue(bitmap.installPixels(setArray))
val result = bitmap.readPixels()!!
assertTrue(bitmap.rowBytes > 0)
assertEquals(16, result.size)
assertContentEquals(setArray, result)
}
}
......@@ -32,10 +32,21 @@ extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skia_BitmapKt__1nSwap
instance->swap(*other);
}
extern "C" JNIEXPORT jobject JNICALL Java_org_jetbrains_skia_BitmapKt__1nGetImageInfo
(JNIEnv* env, jclass jclass, jlong ptr) {
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skia_BitmapKt__1nGetImageInfo
(JNIEnv* env, jclass jclass, jlong ptr, jintArray imageInfoResult, jlongArray colorSpaceResultPtr) {
SkBitmap* instance = reinterpret_cast<SkBitmap*>(static_cast<uintptr_t>(ptr));
return skija::ImageInfo::toJava(env, instance->info());
SkImageInfo imageInfo = instance->info();
jint *result_int = env->GetIntArrayElements(imageInfoResult, NULL);
result_int[0] = instance->width();
result_int[1] = instance->height();
result_int[2] = static_cast<int>(imageInfo.colorType());
result_int[3] = static_cast<int>(imageInfo.alphaType());
env->ReleaseIntArrayElements(imageInfoResult, result_int, 0);
jlong *result_long = env->GetLongArrayElements(colorSpaceResultPtr, NULL);
result_long[0] = reinterpret_cast<jlong>(imageInfo.refColorSpace().release());
env->ReleaseLongArrayElements(colorSpaceResultPtr, result_long, 0);
}
extern "C" JNIEXPORT jint JNICALL Java_org_jetbrains_skia_BitmapKt__1nGetRowBytesAsPixels
......@@ -50,7 +61,7 @@ extern "C" JNIEXPORT jboolean JNICALL Java_org_jetbrains_skia_BitmapKt__1nIsNull
return instance->isNull();
}
extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_BitmapKt__1nGetRowBytes
extern "C" JNIEXPORT jint JNICALL Java_org_jetbrains_skia_BitmapKt__1nGetRowBytes
(JNIEnv* env, jclass jclass, jlong ptr) {
SkBitmap* instance = reinterpret_cast<SkBitmap*>(static_cast<uintptr_t>(ptr));
return instance->rowBytes();
......@@ -93,7 +104,7 @@ extern "C" JNIEXPORT jboolean JNICALL Java_org_jetbrains_skia_BitmapKt__1nComput
}
extern "C" JNIEXPORT jboolean JNICALL Java_org_jetbrains_skia_BitmapKt__1nSetImageInfo
(JNIEnv* env, jclass jclass, jlong ptr, jint width, jint height, jint colorType, jint alphaType, jlong colorSpacePtr, jlong rowBytes) {
(JNIEnv* env, jclass jclass, jlong ptr, jint width, jint height, jint colorType, jint alphaType, jlong colorSpacePtr, jint rowBytes) {
SkBitmap* instance = reinterpret_cast<SkBitmap*>(static_cast<uintptr_t>(ptr));
SkColorSpace* colorSpace = reinterpret_cast<SkColorSpace*>(static_cast<uintptr_t>(colorSpacePtr));
SkImageInfo imageInfo = SkImageInfo::Make(width,
......@@ -117,7 +128,7 @@ extern "C" JNIEXPORT jboolean JNICALL Java_org_jetbrains_skia_BitmapKt__1nAllocP
}
extern "C" JNIEXPORT jboolean JNICALL Java_org_jetbrains_skia_BitmapKt__1nAllocPixelsRowBytes
(JNIEnv* env, jclass jclass, jlong ptr, jint width, jint height, jint colorType, jint alphaType, jlong colorSpacePtr, jlong rowBytes) {
(JNIEnv* env, jclass jclass, jlong ptr, jint width, jint height, jint colorType, jint alphaType, jlong colorSpacePtr, jint rowBytes) {
SkBitmap* instance = reinterpret_cast<SkBitmap*>(static_cast<uintptr_t>(ptr));
SkColorSpace* colorSpace = reinterpret_cast<SkColorSpace*>(static_cast<uintptr_t>(colorSpacePtr));
SkImageInfo imageInfo = SkImageInfo::Make(width,
......@@ -129,7 +140,7 @@ extern "C" JNIEXPORT jboolean JNICALL Java_org_jetbrains_skia_BitmapKt__1nAllocP
}
extern "C" JNIEXPORT jboolean JNICALL Java_org_jetbrains_skia_BitmapKt__1nInstallPixels
(JNIEnv* env, jclass jclass, jlong ptr, jint width, jint height, jint colorType, jint alphaType, jlong colorSpacePtr, jbyteArray pixelsArr, jlong rowBytes) {
(JNIEnv* env, jclass jclass, jlong ptr, jint width, jint height, jint colorType, jint alphaType, jlong colorSpacePtr, jbyteArray pixelsArr, jint rowBytes) {
SkBitmap* instance = reinterpret_cast<SkBitmap*>(static_cast<uintptr_t>(ptr));
SkColorSpace* colorSpace = reinterpret_cast<SkColorSpace*>(static_cast<uintptr_t>(colorSpacePtr));
SkImageInfo imageInfo = SkImageInfo::Make(width,
......@@ -221,8 +232,11 @@ extern "C" JNIEXPORT jboolean JNICALL Java_org_jetbrains_skia_BitmapKt__1nExtrac
return instance->extractSubset(dst, {left, top, right, bottom});
}
extern "C" JNIEXPORT jbyteArray JNICALL Java_org_jetbrains_skia_BitmapKt__1nReadPixels
(JNIEnv* env, jclass jclass, jlong ptr, jint width, jint height, jint colorType, jint alphaType, jlong colorSpacePtr, jlong rowBytes, jint srcX, jint srcY) {
// returns true if readBytes array contains successfully read bytes. returns false otherwise
extern "C" JNIEXPORT jboolean JNICALL Java_org_jetbrains_skia_BitmapKt__1nReadPixels
(JNIEnv* env, jclass jclass, jlong ptr, jint width, jint height, jint colorType, jint alphaType, jlong colorSpacePtr, jint rowBytes, jint srcX, jint srcY, jbyteArray readBytes) {
jbyte *result_bytes = env->GetByteArrayElements(readBytes, NULL);
SkBitmap* instance = reinterpret_cast<SkBitmap*>(static_cast<uintptr_t>(ptr));
SkColorSpace* colorSpace = reinterpret_cast<SkColorSpace*>(static_cast<uintptr_t>(colorSpacePtr));
SkImageInfo imageInfo = SkImageInfo::Make(width,
......@@ -230,23 +244,30 @@ extern "C" JNIEXPORT jbyteArray JNICALL Java_org_jetbrains_skia_BitmapKt__1nRead
static_cast<SkColorType>(colorType),
static_cast<SkAlphaType>(alphaType),
sk_ref_sp<SkColorSpace>(colorSpace));
std::vector<jbyte> pixels(std::min(height, instance->height() - srcY) * rowBytes);
if (instance->readPixels(imageInfo, pixels.data(), rowBytes, srcX, srcY))
return javaByteArray(env, pixels);
else
return nullptr;
if (instance->readPixels(imageInfo, result_bytes, rowBytes, srcX, srcY)) {
env->ReleaseByteArrayElements(readBytes, result_bytes, 0);
return true;
} else {
return false;
}
}
extern "C" JNIEXPORT jobject JNICALL Java_org_jetbrains_skia_BitmapKt__1nExtractAlpha
(JNIEnv* env, jclass jclass, jlong ptr, jlong dstPtr, jlong paintPtr) {
extern "C" JNIEXPORT jboolean JNICALL Java_org_jetbrains_skia_BitmapKt__1nExtractAlpha
(JNIEnv* env, jclass jclass, jlong ptr, jlong dstPtr, jlong paintPtr, jintArray resultPoint) {
SkBitmap* instance = reinterpret_cast<SkBitmap*>(static_cast<uintptr_t>(ptr));
SkBitmap* dst = reinterpret_cast<SkBitmap*>(static_cast<uintptr_t>(dstPtr));
SkPaint* paint = reinterpret_cast<SkPaint*>(static_cast<uintptr_t>(paintPtr));
SkIPoint offset;
if (instance->extractAlpha(dst, paint, &offset))
return skija::IPoint::fromSkIPoint(env, offset);
else
return nullptr;
jint *result_int = env->GetIntArrayElements(resultPoint, NULL);
if (instance->extractAlpha(dst, paint, &offset)) {
result_int[0] = offset.fX;
result_int[1] = offset.fY;
env->ReleaseIntArrayElements(resultPoint, result_int, 0);
return true;
} else {
return false;
}
}
extern "C" JNIEXPORT jobject JNICALL Java_org_jetbrains_skia_BitmapKt__1nPeekPixels
......
......@@ -67,7 +67,7 @@ internal class SoftwareContextHandler(layer: SkiaLayer) : ContextHandler(layer)
val h = (layer.height * scale).toInt().coerceAtLeast(0)
val bytes = storage.readPixels(storage.imageInfo, (w * 4).toLong(), 0, 0)
val bytes = storage.readPixels(storage.imageInfo, (w * 4), 0, 0)
if (bytes != null) {
val buffer = DataBufferByte(bytes, bytes.size)
raster = Raster.createInterleavedRaster(
......
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