diff --git a/fingerprint/infra/nec-bio-sdk/build.gradle.kts b/fingerprint/infra/nec-bio-sdk/build.gradle.kts index 7321fba1bd..d743ef4bb1 100644 --- a/fingerprint/infra/nec-bio-sdk/build.gradle.kts +++ b/fingerprint/infra/nec-bio-sdk/build.gradle.kts @@ -16,12 +16,6 @@ dependencies { //NEC SDK lib and wrapper implementation(libs.nec.wrapper) implementation(libs.nec.lib) - // Image processing libs - // WsqDecoder and BitmapConverter libs are very old and we should consider replacing them but - // they are the only ones that works with wsq images implementation(libs.secugen) - implementation(libs.wsqDecoder) - implementation(libs.bitmapConverter){ - exclude("com.android.support") - } + } diff --git a/fingerprint/infra/nec-bio-sdk/src/main/java/com/simprints/fingerprint/infra/necsdkimpl/NecSdkModule.kt b/fingerprint/infra/nec-bio-sdk/src/main/java/com/simprints/fingerprint/infra/necsdkimpl/NecSdkModule.kt index 95dde732cd..11668ac301 100644 --- a/fingerprint/infra/nec-bio-sdk/src/main/java/com/simprints/fingerprint/infra/necsdkimpl/NecSdkModule.kt +++ b/fingerprint/infra/nec-bio-sdk/src/main/java/com/simprints/fingerprint/infra/necsdkimpl/NecSdkModule.kt @@ -1,5 +1,6 @@ package com.simprints.fingerprint.infra.necsdkimpl +import com.secugen.WSQConverter import com.simprints.fingerprint.infra.basebiosdk.FingerprintBioSdk import com.simprints.fingerprint.infra.necsdkimpl.acquisition.image.FingerprintImageProviderImpl import com.simprints.fingerprint.infra.necsdkimpl.acquisition.template.FingerprintTemplateAcquisitionSettings @@ -10,7 +11,6 @@ import com.simprints.fingerprint.infra.necsdkimpl.matching.FingerprintMatcherImp import com.simprints.fingerprint.infra.necsdkimpl.matching.NecMatchingSettings import com.simprints.necwrapper.nec.NEC import com.simprints.sgimagecorrection.SecugenImageCorrection -import com.ygoular.bitmapconverter.BitmapConverter import dagger.Module import dagger.Provides import dagger.hilt.InstallIn @@ -49,7 +49,7 @@ object NecSdkModule { @Provides @Singleton - internal fun provideBitmapConverter() = BitmapConverter() + internal fun provideWSQConverter () = WSQConverter() @Provides @Singleton diff --git a/fingerprint/infra/nec-bio-sdk/src/main/java/com/simprints/fingerprint/infra/necsdkimpl/acquisition/template/DecodeWSQImageUseCase.kt b/fingerprint/infra/nec-bio-sdk/src/main/java/com/simprints/fingerprint/infra/necsdkimpl/acquisition/template/DecodeWSQImageUseCase.kt deleted file mode 100644 index 2fed25d07d..0000000000 --- a/fingerprint/infra/nec-bio-sdk/src/main/java/com/simprints/fingerprint/infra/necsdkimpl/acquisition/template/DecodeWSQImageUseCase.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.simprints.fingerprint.infra.necsdkimpl.acquisition.template - -import com.gemalto.wsq.WSQDecoder -import com.simprints.fingerprint.infra.basebiosdk.exceptions.BioSdkException -import com.simprints.fingerprint.infra.scanner.domain.fingerprint.RawUnprocessedImage -import com.ygoular.bitmapconverter.BitmapConverter -import com.ygoular.bitmapconverter.BitmapFormat -import javax.inject.Inject - - -class DecodeWSQImageUseCase @Inject constructor (private val bitmapConverter: BitmapConverter) { - - /** - * Decode WSQ images - * - * @param imageBytes The WSQ encoded image - * - * @return the decoded raw image bytes array - */ - operator fun invoke(imageBytes: RawUnprocessedImage): FingerprintRawImage { - if (!imageBytes.isValidFormat()) { - throw BioSdkException.ImageDecodingException() - } - val decodingResult = WSQDecoder.decode(imageBytes.imageData) - ?:throw BioSdkException.ImageDecodingException() - val decodedBitmap = decodingResult.bitmap - - // WSQ decoder produces rgp images, NEC only process gray scale raw images. - // So we convert the decoded bitmap to gray scale. - val rawImageBytes = - bitmapConverter.convert(decodingResult.bitmap, BitmapFormat.BITMAP_8_BIT_COLOR) - - val decodedImage = FingerprintRawImage( - imageBytes.un20SerialNumber, - rawImageBytes, - decodedBitmap.width, - decodedBitmap.height, - imageBytes.brightness - ) - // Recycle the bitmap to free memory and avoid OutOfMemoryException - decodingResult.bitmap.recycle() - return decodedImage - } -} diff --git a/fingerprint/infra/nec-bio-sdk/src/main/java/com/simprints/fingerprint/infra/necsdkimpl/acquisition/template/FingerprintTemplateProviderImpl.kt b/fingerprint/infra/nec-bio-sdk/src/main/java/com/simprints/fingerprint/infra/necsdkimpl/acquisition/template/FingerprintTemplateProviderImpl.kt index ce79571342..9f886fff1c 100644 --- a/fingerprint/infra/nec-bio-sdk/src/main/java/com/simprints/fingerprint/infra/necsdkimpl/acquisition/template/FingerprintTemplateProviderImpl.kt +++ b/fingerprint/infra/nec-bio-sdk/src/main/java/com/simprints/fingerprint/infra/necsdkimpl/acquisition/template/FingerprintTemplateProviderImpl.kt @@ -1,5 +1,7 @@ package com.simprints.fingerprint.infra.necsdkimpl.acquisition.template +import com.secugen.RawImage +import com.secugen.WSQConverter import com.simprints.core.DispatcherIO import com.simprints.fingerprint.infra.basebiosdk.acquisition.FingerprintTemplateProvider import com.simprints.fingerprint.infra.basebiosdk.acquisition.domain.TemplateResponse @@ -14,7 +16,7 @@ import javax.inject.Inject internal class FingerprintTemplateProviderImpl @Inject constructor( private val fingerprintCaptureWrapperFactory: FingerprintCaptureWrapperFactory, - private val decodeWSQImageUseCase: DecodeWSQImageUseCase, + private val wsqConverter: WSQConverter, private val secugenImageCorrection: SecugenImageCorrection, private val acquireImageDistortionConfigurationUseCase: AcquireImageDistortionConfigurationUseCase, private val calculateNecImageQualityUseCase: CalculateNecImageQualityUseCase, @@ -40,15 +42,19 @@ internal class FingerprintTemplateProviderImpl @Inject constructor( // Always require a new image from the scanner using the minimum resolution as we will // process it using secugen image correction log("Acquiring unprocessed image") - val unprocessedImage = captureWrapper.acquireUnprocessedImage( + val rawFingerprintScan = captureWrapper.acquireUnprocessedImage( Dpi(MIN_CAPTURE_DPI) ).rawUnprocessedImage - captureProcessedImageCache.recentlyCapturedImage = unprocessedImage.imageData + captureProcessedImageCache.recentlyCapturedImage = rawFingerprintScan.imageData log("Unprocessed image acquired, processing it") - val decodedImage = decodeWSQImageUseCase(unprocessedImage) - log("Image decoded successfully ${decodedImage.resolution}") + val decodedImage = wsqConverter.fromWSQToRaw(rawFingerprintScan.imageData) log("processing image using secugen image correction") - val secugenProcessedImage = processImage(settings, decodedImage) + val secugenProcessedImage = processImage( + settings, + decodedImage, + rawFingerprintScan.un20SerialNumber, + rawFingerprintScan.brightness + ) log("quality checking image using nec sdk") val qualityScore = calculateNecImageQualityUseCase(secugenProcessedImage) log("quality score is $qualityScore the threshold is ${settings.qualityThreshold}") @@ -73,16 +79,17 @@ internal class FingerprintTemplateProviderImpl @Inject constructor( private suspend fun processImage( settings: FingerprintTemplateAcquisitionSettings, - rawImage: FingerprintRawImage + rawImage: RawImage, + un20SerialNumber: ByteArray, + brightness: Byte ): FingerprintImage { val scannerConfig = SecugenImageCorrection.ScannerConfig( acquireImageDistortionConfigurationUseCase(), settings.processingResolution?.value ?: DEFAULT_RESOLUTION, - rawImage.un20SerialNumber, - rawImage.brightness + un20SerialNumber, + brightness ) - val processedImage = - secugenImageCorrection.processRawImage(rawImage.imageBytes, scannerConfig) + val processedImage = secugenImageCorrection.processRawImage(rawImage.bytes, scannerConfig) return FingerprintImage( processedImage.imageBytes, processedImage.width, diff --git a/fingerprint/infra/nec-bio-sdk/src/test/java/com/simprints/fingerprint/infra/necsdkimpl/acquisition/template/DecodeWSQImageUseCaseTest.kt b/fingerprint/infra/nec-bio-sdk/src/test/java/com/simprints/fingerprint/infra/necsdkimpl/acquisition/template/DecodeWSQImageUseCaseTest.kt deleted file mode 100644 index 6e8219f260..0000000000 --- a/fingerprint/infra/nec-bio-sdk/src/test/java/com/simprints/fingerprint/infra/necsdkimpl/acquisition/template/DecodeWSQImageUseCaseTest.kt +++ /dev/null @@ -1,90 +0,0 @@ -package com.simprints.fingerprint.infra.necsdkimpl.acquisition.template - - -import android.graphics.Bitmap -import com.gemalto.wsq.WSQDecoder -import com.google.common.truth.Truth -import com.simprints.fingerprint.infra.basebiosdk.exceptions.BioSdkException -import com.simprints.fingerprint.infra.scanner.domain.fingerprint.RawUnprocessedImage -import com.ygoular.bitmapconverter.BitmapConverter -import io.mockk.MockKAnnotations -import io.mockk.every -import io.mockk.impl.annotations.MockK -import io.mockk.mockkStatic -import org.junit.Before -import org.junit.Test - -class DecodeWSQImageUseCaseTest { - - private val convertedImageBytesMock: ByteArray= emptyArray().toByteArray() - - @MockK(relaxed = true) - lateinit var mockedDecodeResult: WSQDecoder.WSQDecodedImage - - @MockK(relaxed = true) - lateinit var bitmapConverter: BitmapConverter - - @MockK(relaxed = true) - lateinit var bitmap: Bitmap - - private lateinit var decodeWsqImageUseCase: DecodeWSQImageUseCase - - companion object { - private val UNPROCESSED_IMAGE = RawUnprocessedImage( - byteArrayOf( - 0x05, 0x06, 0x07, 0x08, 0x05, 0x06, 0x07, 0x08, - 0x05, 0x06, 0x07, 0x08, 0x05, 0x06, 0x07, 0x08, 0x05, 0x06, 0x07, 0x08, - 0x05, 0x06, 0x07, 0x08, 0x05, 0x06, 0x07, 0x08 - ) - ) - } - - @Before - fun setup() { - MockKAnnotations.init(this) - mockkStatic(WSQDecoder::class) - decodeWsqImageUseCase = DecodeWSQImageUseCase(bitmapConverter) - buildDecodedImage() - } - - private fun buildDecodedImage() { - every { bitmapConverter.convert(any(), any()) } returns convertedImageBytesMock - every { mockedDecodeResult.bitmap } returns bitmap - every { mockedDecodeResult.ppi } returns 0 - } - - @Test - fun `test decode image success`() { - // Given - every { WSQDecoder.decode(any()) } returns mockedDecodeResult - - // When - val result = decodeWsqImageUseCase(UNPROCESSED_IMAGE) - - // Then - Truth.assertThat(result.imageBytes).isEqualTo(convertedImageBytesMock) - } - - @Test(expected = BioSdkException.ImageDecodingException::class) - fun `test decode image failure`() { - // Given - every { WSQDecoder.decode(any()) } returns null - - // When - decodeWsqImageUseCase(UNPROCESSED_IMAGE) - // Then the exception is thrown - } - - @Test(expected = BioSdkException.ImageDecodingException::class) - fun `test decode empty image should fail`() { - // Given - every { WSQDecoder.decode(any()) } returns mockedDecodeResult - - // When - decodeWsqImageUseCase(RawUnprocessedImage(byteArrayOf(0))) - // Then the exception is thrown - - } - - -} diff --git a/fingerprint/infra/nec-bio-sdk/src/test/java/com/simprints/fingerprint/infra/necsdkimpl/acquisition/template/FingerprintTemplateProviderImplTest.kt b/fingerprint/infra/nec-bio-sdk/src/test/java/com/simprints/fingerprint/infra/necsdkimpl/acquisition/template/FingerprintTemplateProviderImplTest.kt index c3e3130f01..9c0f6d354a 100644 --- a/fingerprint/infra/nec-bio-sdk/src/test/java/com/simprints/fingerprint/infra/necsdkimpl/acquisition/template/FingerprintTemplateProviderImplTest.kt +++ b/fingerprint/infra/nec-bio-sdk/src/test/java/com/simprints/fingerprint/infra/necsdkimpl/acquisition/template/FingerprintTemplateProviderImplTest.kt @@ -1,5 +1,6 @@ package com.simprints.fingerprint.infra.necsdkimpl.acquisition.template +import com.secugen.WSQConverter import androidx.arch.core.executor.testing.InstantTaskExecutorRule import com.google.common.truth.Truth import com.simprints.fingerprint.infra.basebiosdk.acquisition.domain.TemplateResponse @@ -40,7 +41,7 @@ class FingerprintTemplateProviderImplTest { private lateinit var extractNecTemplateUseCase: ExtractNecTemplateUseCase @RelaxedMockK - private lateinit var decodeWsqImageUseCase: DecodeWSQImageUseCase + private lateinit var wsqConverter: WSQConverter @RelaxedMockK private lateinit var processedImageCache: ProcessedImageCache @@ -68,7 +69,7 @@ class FingerprintTemplateProviderImplTest { )) fingerprintTemplateProviderImpl = FingerprintTemplateProviderImpl( fingerprintCaptureWrapperFactory = fingerprintCaptureWrapperFactory, - decodeWSQImageUseCase = decodeWsqImageUseCase, + wsqConverter = wsqConverter, secugenImageCorrection = secugenImageCorrection, acquireImageDistortionConfigurationUseCase = acquireImageDistortionConfigurationUseCase, calculateNecImageQualityUseCase = calculateNecImageQualityUseCase, @@ -104,7 +105,7 @@ class FingerprintTemplateProviderImplTest { coVerify { captureWrapper .acquireUnprocessedImage(any()) - decodeWsqImageUseCase.invoke(any()) + wsqConverter.fromWSQToRaw(any()) processedImageCache.recentlyCapturedImage = any() secugenImageCorrection.processRawImage(any(), any()) calculateNecImageQualityUseCase.invoke(any()) @@ -130,7 +131,7 @@ class FingerprintTemplateProviderImplTest { coVerify { captureWrapper .acquireUnprocessedImage(any()) - decodeWsqImageUseCase.invoke(any()) + wsqConverter.fromWSQToRaw(any()) processedImageCache.recentlyCapturedImage = any() secugenImageCorrection.processRawImage(any(), any()) calculateNecImageQualityUseCase.invoke(any()) @@ -157,7 +158,7 @@ class FingerprintTemplateProviderImplTest { coVerify { captureWrapper .acquireUnprocessedImage(any()) - decodeWsqImageUseCase.invoke(any()) + wsqConverter.fromWSQToRaw(any()) processedImageCache.recentlyCapturedImage = any() secugenImageCorrection.processRawImage(any(), any()) calculateNecImageQualityUseCase.invoke(any()) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 567f5c633d..1ae8c926da 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -70,9 +70,7 @@ libsimprints_version = "2024.1.1" simmatcher_version = "1.2.0" roc_wrapper_version = "1.23" nec_version = "1.5.0" -secugen_version = "1.0.0" -wsq_version = "1.2" -bitmapConverter_version = "0.2.0" +secugen_version = "1.1.0" junit_version = "4.13.2" junit_ext_version = "1.1.5" @@ -211,12 +209,6 @@ nec-lib = { module = "com.nec:lib", version.ref = "nec_version" } # secugen sdk hosted in https://github.com/Simprints/secugen-wrapper secugen = { module = "com.simprints:secugenwrapper", version.ref = "secugen_version" } -#WSQ -wsqDecoder = { module = "com.gemalto.wsq:wsq-android", version.ref = "wsq_version" } -# BitmapConverter -bitmapConverter= {module= "com.github.yoanngoular:bitmapconverter", version.ref = "bitmapConverter_version"} - - #hilt hilt = { module = "com.google.dagger:hilt-android", version.ref = "hilt_version" } hilt-kapt = { module = "com.google.dagger:hilt-compiler", version.ref = "hilt_version" }