From 561e30ea6aded84e6a93875f615b1c632154a290 Mon Sep 17 00:00:00 2001 From: sh Date: Thu, 21 May 2026 16:06:42 +0000 Subject: [PATCH] desktop: add WebP ImageIO plugin (TwelveMonkeys) so the image picker can decode WebP --- apps/multiplatform/common/build.gradle.kts | 4 ++++ .../kotlin/chat/simplex/app/MetadataStripTest.kt | 11 +++++++++++ 2 files changed, 15 insertions(+) diff --git a/apps/multiplatform/common/build.gradle.kts b/apps/multiplatform/common/build.gradle.kts index 98845365fc..e63f0f0b8e 100644 --- a/apps/multiplatform/common/build.gradle.kts +++ b/apps/multiplatform/common/build.gradle.kts @@ -151,6 +151,10 @@ kotlin { implementation("com.github.NanoHttpd.nanohttpd:nanohttpd:efb2ebf") implementation("com.github.NanoHttpd.nanohttpd:nanohttpd-websocket:efb2ebf") implementation("com.squareup.okhttp3:okhttp:4.12.0") + // WebP decoder for ImageIO — desktop's javax.imageio.ImageIO ships only JPEG/PNG/GIF/BMP + // by default. Without this, picking a WebP via the image picker falls into the catch-block + // at Utils.desktop.kt:getBitmapFromUri and shows "image cannot be decoded". + implementation("com.twelvemonkeys.imageio:imageio-webp:3.11.0") } } val desktopTest by getting diff --git a/apps/multiplatform/common/src/commonTest/kotlin/chat/simplex/app/MetadataStripTest.kt b/apps/multiplatform/common/src/commonTest/kotlin/chat/simplex/app/MetadataStripTest.kt index febe518e67..07d42a349b 100644 --- a/apps/multiplatform/common/src/commonTest/kotlin/chat/simplex/app/MetadataStripTest.kt +++ b/apps/multiplatform/common/src/commonTest/kotlin/chat/simplex/app/MetadataStripTest.kt @@ -937,6 +937,17 @@ class CorruptionCheckTest { assertTrue(image.width > 0 && image.height > 0) } + @Test fun testStrippedWebpDecodable() { + // Verifies that (a) the WebP stripper produces a valid file and (b) the TwelveMonkeys + // imageio-webp plugin is registered on desktop so `ImageIO.read` doesn't return null — + // without the plugin the desktop image picker rejects every WebP with "cannot be decoded". + val input = loadResource("webp_with_exif.webp") + val output = stripWebPMetadata(input) + val image = javax.imageio.ImageIO.read(java.io.ByteArrayInputStream(output)) + assertNotNull(image, "Stripped WebP should be decodable via ImageIO") + assertTrue(image.width > 0 && image.height > 0) + } + @Test fun testStrippedMp4HasValidStructure() { val inputFile = File.createTempFile("test_", ".mp4") inputFile.writeBytes(loadResource("mp4_with_gps.mp4"))