From 92a3331902e8e54733de39d833b4b0f793ff5f94 Mon Sep 17 00:00:00 2001 From: Ralph Gasser Date: Tue, 27 Aug 2024 07:53:18 +0200 Subject: [PATCH] Explicitly adds Twelvemonkeys and NightMonkeys plugin for advanced image format support. Makes some improvements in how ImageDecoder handles itself. Signed-off-by: Ralph Gasser --- gradle.properties | 2 ++ vitrivr-engine-index/build.gradle | 11 +++++++++++ .../engine/index/decode/ImageDecoder.kt | 18 +++++++++++++----- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/gradle.properties b/gradle.properties index d5f57f686..06757fc46 100644 --- a/gradle.properties +++ b/gradle.properties @@ -17,10 +17,12 @@ version_kotlinx_datetime=0.6.1 version_kotlinlogging = 7.0.0 version_log4j2=2.23.1 version_metadataextractor=2.19.0 +version_nightmonkeys=1.0.0 version_picnic=0.7.0 version_protobuf=3.25.4 version_scrimage=4.2.0 version_slf4j=2.0.16 +version_twelvemonkeys=3.11.0 version_jogl=2.3.2 version_joml=1.9.25 version_ktor=2.3.12 diff --git a/vitrivr-engine-index/build.gradle b/vitrivr-engine-index/build.gradle index 9efc97a40..9afbfc482 100644 --- a/vitrivr-engine-index/build.gradle +++ b/vitrivr-engine-index/build.gradle @@ -14,6 +14,17 @@ dependencies { /** ScrImage (used for image resizing). */ implementation group: 'com.sksamuel.scrimage', name: 'scrimage-core', version: version_scrimage + /** TwelveMonkeys for image support */ + runtimeOnly group: 'com.twelvemonkeys.imageio', name: 'imageio-core', version: version_twelvemonkeys + runtimeOnly group: 'com.twelvemonkeys.imageio', name: 'imageio-tiff', version: version_twelvemonkeys + runtimeOnly group: 'com.twelvemonkeys.imageio', name: 'imageio-jpeg', version: version_twelvemonkeys + runtimeOnly group: 'com.twelvemonkeys.imageio', name: 'imageio-psd', version: version_twelvemonkeys + runtimeOnly group: 'com.twelvemonkeys.imageio', name: 'imageio-bmp', version: version_twelvemonkeys + runtimeOnly group: 'com.twelvemonkeys.imageio', name: 'imageio-webp', version: version_twelvemonkeys + runtimeOnly group: 'com.twelvemonkeys.imageio', name: 'imageio-pdf', version: version_twelvemonkeys + + /** NightMonkeys for advancaded image formats (HEIF & WEBP). */ + implementation group: 'com.github.gotson.nightmonkeys', name: 'imageio-heif', version: version_nightmonkeys } /* Publication of vitrivr engine index to Maven Central. */ diff --git a/vitrivr-engine-index/src/main/kotlin/org/vitrivr/engine/index/decode/ImageDecoder.kt b/vitrivr-engine-index/src/main/kotlin/org/vitrivr/engine/index/decode/ImageDecoder.kt index 9c0116732..3025e04ef 100644 --- a/vitrivr-engine-index/src/main/kotlin/org/vitrivr/engine/index/decode/ImageDecoder.kt +++ b/vitrivr-engine-index/src/main/kotlin/org/vitrivr/engine/index/decode/ImageDecoder.kt @@ -25,7 +25,7 @@ private val logger: KLogger = KotlinLogging.logger {} * A [Decoder] that can decode [ImageContent] from a [Source] of [MediaType.IMAGE]. * * @author Luca Rossetto - * @version 1.1.0 + * @version 1.1.1 */ class ImageDecoder : DecoderFactory { @@ -45,13 +45,18 @@ class ImageDecoder : DecoderFactory { override fun toFlow(scope: CoroutineScope): Flow = this.input.toFlow(scope).mapNotNull { sourceRetrievable -> val source = sourceRetrievable.filteredAttribute(SourceAttribute::class.java)?.source ?: return@mapNotNull null if (source.type != MediaType.IMAGE) { - logger.debug { "In flow: Skipping source ${source.name} (${source.sourceId}) because it is not of type IMAGE." } + logger.debug { "Skipping source ${source.name} (${source.sourceId}) because it is not of type IMAGE." } return@mapNotNull null } - logger.debug { "In flow: Decoding source ${source.name} (${source.sourceId})" } + logger.debug { "Decoding source ${source.name} (${source.sourceId})" } try { val content = source.newInputStream().use { - this.context.contentFactory.newImageContent(ImageIO.read(it)) + val image = ImageIO.read(it) + if (image == null) { + logger.warn { "Failed to decode image from source '${source.name}' (${source.sourceId})." } + return@mapNotNull null + } + this.context.contentFactory.newImageContent(image) } sourceRetrievable.addContent(content) sourceRetrievable.addAttribute(ContentAuthorAttribute(content.id, this.name)) @@ -60,7 +65,10 @@ class ImageDecoder : DecoderFactory { /* Return ingested. */ sourceRetrievable } catch (e: IOException) { - logger.error(e) { "Failed to decode image from source '${source.name}' (${source.sourceId})." } + logger.error(e) { "Failed to decode image from source '${source.name}' (${source.sourceId}) due to IO exception: ${e.message}" } + null + } catch (e: Throwable) { + logger.error(e) { "Failed to decode image from source '${source.name}' (${source.sourceId}) due to exception: ${e.message}" } null } }