Skip to content

Commit cb216c6

Browse files
committed
QrCodeFromFileScanner: more efficiently downscale images and release memory
Signed-off-by: Jason A. Donenfeld <[email protected]>
1 parent d45b1ea commit cb216c6

File tree

1 file changed

+16
-44
lines changed

1 file changed

+16
-44
lines changed

ui/src/main/java/com/wireguard/android/util/QrCodeFromFileScanner.kt

Lines changed: 16 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ class QrCodeFromFileScanner(
2929
private val contentResolver: ContentResolver,
3030
private val reader: Reader,
3131
) {
32-
3332
private fun scanBitmapForResult(source: Bitmap): Result {
3433
val width = source.width
3534
val height = source.height
@@ -40,55 +39,28 @@ class QrCodeFromFileScanner(
4039
return reader.decode(bBitmap, mapOf(DecodeHintType.TRY_HARDER to true))
4140
}
4241

43-
private fun downscaleBitmap(source: Bitmap, scaledSize: Int): Bitmap {
44-
45-
val originalWidth = source.width
46-
val originalHeight = source.height
47-
48-
var newWidth = -1
49-
var newHeight = -1
50-
val multFactor: Float
51-
52-
when {
53-
originalHeight > originalWidth -> {
54-
newHeight = scaledSize
55-
multFactor = originalWidth.toFloat() / originalHeight.toFloat()
56-
newWidth = (newHeight * multFactor).toInt()
57-
}
58-
59-
originalWidth > originalHeight -> {
60-
newWidth = scaledSize
61-
multFactor = originalHeight.toFloat() / originalWidth.toFloat()
62-
newHeight = (newWidth * multFactor).toInt()
63-
}
64-
65-
originalHeight == originalWidth -> {
66-
newHeight = scaledSize
67-
newWidth = scaledSize
68-
}
69-
}
70-
return Bitmap.createScaledBitmap(source, newWidth, newHeight, false)
71-
}
72-
7342
private fun doScan(data: Uri): Result {
7443
Log.d(TAG, "Starting to scan an image: $data")
7544
contentResolver.openInputStream(data).use { inputStream ->
76-
val originalBitmap = BitmapFactory.decodeStream(inputStream)
77-
?: throw IllegalArgumentException("Can't decode stream to Bitmap")
78-
79-
return try {
80-
scanBitmapForResult(originalBitmap).also {
81-
Log.d(TAG, "Found result in original image")
45+
var bitmap: Bitmap? = null
46+
var firstException: Throwable? = null
47+
for (i in arrayOf(1, 2, 4, 8, 16, 32, 64, 128)) {
48+
try {
49+
val options = BitmapFactory.Options()
50+
options.inSampleSize = i
51+
bitmap = BitmapFactory.decodeStream(inputStream, null, options)
52+
?: throw IllegalArgumentException("Can't decode stream for bitmap")
53+
return scanBitmapForResult(bitmap)
54+
} catch (e: Throwable) {
55+
bitmap?.recycle()
56+
System.gc()
57+
Log.e(TAG, "Original image scan at scale factor $i finished with error: $e")
58+
if (firstException == null)
59+
firstException = e
8260
}
83-
} catch (e: Throwable) {
84-
Log.e(TAG, "Original image scan finished with error: $e, will try downscaled image")
85-
val scaleBitmap = downscaleBitmap(originalBitmap, 500)
86-
scanBitmapForResult(originalBitmap).also { scaleBitmap.recycle() }
87-
} finally {
88-
originalBitmap.recycle()
8961
}
62+
throw Exception(firstException)
9063
}
91-
9264
}
9365

9466
/**

0 commit comments

Comments
 (0)