Skip to content

Commit

Permalink
Add fun Image.Companion.makeFromEncoded(nsData: NSData): Image (#873)
Browse files Browse the repository at this point in the history
  • Loading branch information
eymar authored Feb 14, 2024
1 parent 1d380da commit e463c57
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 1 deletion.
2 changes: 1 addition & 1 deletion skiko/src/commonMain/kotlin/org/jetbrains/skia/Image.kt
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ private external fun _nMakeFromPixmap(pixmapPtr: NativePointer): NativePointer

@ExternalSymbolName("org_jetbrains_skia_Image__1nMakeFromEncoded")
@ModuleImport("./skiko.mjs", "org_jetbrains_skia_Image__1nMakeFromEncoded")
private external fun _nMakeFromEncoded(bytes: InteropPointer, encodedLength: Int): NativePointer
internal external fun _nMakeFromEncoded(bytes: InteropPointer, encodedLength: Int): NativePointer

@ExternalSymbolName("org_jetbrains_skia_Image__1nEncodeToData")
@ModuleImport("./skiko.mjs", "org_jetbrains_skia_Image__1nEncodeToData")
Expand Down
14 changes: 14 additions & 0 deletions skiko/src/darwinMain/kotlin/org/jetbrains/skia/Image.darwin.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.jetbrains.skia

import platform.Foundation.NSData
import kotlin.native.internal.NativePtr

fun Image.Companion.makeFromEncoded(nsData: NSData): Image {
val ptr = nsData.bytes?.rawValue ?: NativePtr.NULL
require(ptr != NativePtr.NULL) { "Failed to Image::makeFromEncoded" }

// skia makes an internal copy of the nsData bytes
val imgPtr = _nMakeFromEncoded(ptr, nsData.length.toInt())
require(imgPtr != NativePtr.NULL) { "Failed to Image::makeFromEncoded" }
return Image(imgPtr)
}
54 changes: 54 additions & 0 deletions skiko/src/darwinTest/kotlin/org/jetbrains/skia/ImageTest.darwin.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package org.jetbrains.skia

import kotlinx.cinterop.ExperimentalForeignApi
import kotlinx.cinterop.addressOf
import kotlinx.cinterop.pin
import platform.Foundation.NSData
import platform.Foundation.dataWithBytes
import kotlin.test.Test
import kotlin.test.assertEquals

class ImageTestDarwin {

@Test
fun canCreateFromEncodedNsData() {

val bytes = intArrayOf(
0xCA, 0xDA, 0xCA, 0xC9, 0xA3,
0xAC, 0xA8, 0x89, 0xA7, 0x87,
0x9B, 0xB5, 0xE5, 0x95, 0x46,
0x90, 0x81, 0xC5, 0x71, 0x33,
0x75, 0x55, 0x44, 0x40, 0x30
).map { it.toByte() }.toByteArray()

val imageInfo = ImageInfo(
width = 5, height = 5,
colorType = ColorType.GRAY_8,
alphaType = ColorAlphaType.OPAQUE
)

val image = Image.makeRaster(imageInfo, bytes, 5)
val data = image.encodeToData()!!
val originalBitmap = Bitmap.makeFromImage(image)

val nsData = createNSDataFromByteArray(data.bytes)
val imageFromNsData = Image.makeFromEncoded(nsData)
val bitmapFromNsData = Bitmap.makeFromImage(imageFromNsData)

assertEquals(imageInfo.height, imageFromNsData.imageInfo.height)
assertEquals(imageInfo.width, imageFromNsData.imageInfo.width)
assertEquals(imageInfo.colorAlphaType, imageFromNsData.imageInfo.colorAlphaType)
assertEquals(imageInfo.colorType, imageFromNsData.imageInfo.colorType)

repeat(5) { x ->
repeat(5) { y ->
assertEquals(originalBitmap.getColor(x, y), bitmapFromNsData.getColor(x, y))
}
}
}
}

@OptIn(ExperimentalForeignApi::class)
fun createNSDataFromByteArray(bytes: ByteArray): NSData {
return NSData.dataWithBytes(bytes.pin().addressOf(0), bytes.size.toULong())
}

0 comments on commit e463c57

Please sign in to comment.