1package com.peachpasswords.codex23import androidx.camera.core.ImageProxy4import com.google.zxing.BinaryBitmap5import com.google.zxing.DecodeHintType6import com.google.zxing.PlanarYUVLuminanceSource7import com.google.zxing.aztec.AztecReader8import com.google.zxing.common.GlobalHistogramBinarizer9import com.google.zxing.common.HybridBinarizer1011121314151617181920object CodexAztecFrame {2122 2324252627 fun decode(image: ImageProxy): String? {28 val plane = image.planes.getOrNull(0) ?: return null29 val buffer = plane.buffer30 val data = ByteArray(buffer.remaining())31 buffer.get(data)3233 val width = image.width34 val height = image.height35 val rowStride = plane.rowStride3637 38 39 val luma: ByteArray = if (rowStride == width) {40 data41 } else {42 val packed = ByteArray(width * height)43 for (row in 0 until height) {44 System.arraycopy(data, row * rowStride, packed, row * width, width)45 }46 packed47 }4849 val source = PlanarYUVLuminanceSource(50 luma, width, height, 0, 0, width, height, false,51 )52 val hints = mapOf(DecodeHintType.TRY_HARDER to true)53 54 55 val attempts = listOf(56 BinaryBitmap(HybridBinarizer(source)),57 BinaryBitmap(GlobalHistogramBinarizer(source)),58 BinaryBitmap(HybridBinarizer(source.rotateCounterClockwise())),59 )60 for (binary in attempts) {61 try {62 return AztecReader().decode(binary, hints).text63 } catch (_: Exception) {64 65 }66 }67 return null68 }69}