Skip to content

Commit f1da57d

Browse files
authored
Correctly close resources in BitmapUtils. (#440)
* Correctly close resources in BitmapUtils. * Code Review.
1 parent 51de25a commit f1da57d

File tree

3 files changed

+32
-53
lines changed

3 files changed

+32
-53
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
1414
- Added options to customize colors of toolbar back button, title and menu texts. [#437](https://github.com/CanHub/Android-Image-Cropper/issues/437)
1515
### Fixed
1616
- Fixed and issue where setting toolbar color to white would do nothing. [#437](https://github.com/CanHub/Android-Image-Cropper/issues/437)
17+
- Correctly close resources in BitmapUtils. [#440](https://github.com/CanHub/Android-Image-Cropper/issues/440)
1718

1819
## [4.3.2] - 08/09/2022
1920
### Fixed

cropper/src/main/java/com/canhub/cropper/BitmapCroppingWorkerJob.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ class BitmapCroppingWorkerJob(
149149
this.sampleSize = sampleSize
150150
}
151151

152-
constructor(uri: Uri?, sampleSize: Int) {
152+
constructor(uri: Uri, sampleSize: Int) {
153153
bitmap = null
154154
this.uri = uri
155155
error = null

cropper/src/main/java/com/canhub/cropper/BitmapUtils.kt

Lines changed: 30 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,9 @@ import androidx.exifinterface.media.ExifInterface
1717
import com.canhub.cropper.CropImageView.RequestSizeOptions
1818
import com.canhub.cropper.common.CommonVersionCheck.isAtLeastQ29
1919
import com.canhub.cropper.utils.getUriForFile
20-
import java.io.Closeable
2120
import java.io.File
2221
import java.io.FileNotFoundException
2322
import java.io.IOException
24-
import java.io.InputStream
25-
import java.io.OutputStream
2623
import java.lang.ref.WeakReference
2724
import javax.microedition.khronos.egl.EGL10
2825
import javax.microedition.khronos.egl.EGLConfig
@@ -426,23 +423,19 @@ internal object BitmapUtils {
426423
compressFormat: CompressFormat,
427424
compressQuality: Int,
428425
customOutputUri: Uri?,
429-
): Uri? {
426+
): Uri {
430427
val newUri = customOutputUri ?: buildUri(context, compressFormat)
431-
var outputStream: OutputStream? = null
432-
try {
433-
outputStream = context.contentResolver.openOutputStream(newUri!!, WRITE_AND_TRUNCATE)
434428

435-
bitmap.compress(compressFormat, compressQuality, outputStream)
436-
} finally {
437-
closeSafe(outputStream)
429+
return context.contentResolver.openOutputStream(newUri, WRITE_AND_TRUNCATE).use {
430+
bitmap.compress(compressFormat, compressQuality, it)
431+
newUri
438432
}
439-
return newUri
440433
}
441434

442435
private fun buildUri(
443436
context: Context,
444437
compressFormat: CompressFormat
445-
): Uri? =
438+
): Uri =
446439
try {
447440
val ext = when (compressFormat) {
448441
CompressFormat.JPEG -> ".jpg"
@@ -668,16 +661,12 @@ internal object BitmapUtils {
668661
*/
669662
@Throws(FileNotFoundException::class)
670663
private fun decodeImageForOption(resolver: ContentResolver, uri: Uri): BitmapFactory.Options {
671-
var stream: InputStream? = null
672-
return try {
673-
stream = resolver.openInputStream(uri)
664+
return resolver.openInputStream(uri).use {
674665
val options = BitmapFactory.Options()
675666
options.inJustDecodeBounds = true
676-
BitmapFactory.decodeStream(stream, EMPTY_RECT, options)
667+
BitmapFactory.decodeStream(it, EMPTY_RECT, options)
677668
options.inJustDecodeBounds = false
678669
options
679-
} finally {
680-
closeSafe(stream)
681670
}
682671
}
683672

@@ -692,14 +681,12 @@ internal object BitmapUtils {
692681
options: BitmapFactory.Options
693682
): Bitmap? {
694683
do {
695-
var stream: InputStream? = null
696-
try {
697-
stream = resolver.openInputStream(uri)
698-
return BitmapFactory.decodeStream(stream, EMPTY_RECT, options)
699-
} catch (e: OutOfMemoryError) {
700-
options.inSampleSize *= 2
701-
} finally {
702-
closeSafe(stream)
684+
resolver.openInputStream(uri).use {
685+
try {
686+
return BitmapFactory.decodeStream(it, EMPTY_RECT, options)
687+
} catch (e: OutOfMemoryError) {
688+
options.inSampleSize *= 2
689+
}
703690
}
704691
} while (options.inSampleSize <= 512)
705692
throw CropException.FailedToDecodeImage(uri)
@@ -727,21 +714,25 @@ internal object BitmapUtils {
727714
rect.width(), rect.height(), reqWidth, reqHeight
728715
)
729716
)
730-
val stream = context.contentResolver.openInputStream(uri)
731-
val decoder = BitmapRegionDecoder.newInstance(stream!!, false)
732-
do {
717+
718+
context.contentResolver.openInputStream(uri).use {
719+
val decoder = BitmapRegionDecoder.newInstance(it!!, false)
720+
733721
try {
734-
return BitmapSampled(
735-
decoder!!.decodeRegion(rect, options),
736-
options.inSampleSize
737-
)
738-
} catch (e: OutOfMemoryError) {
739-
options.inSampleSize *= 2
722+
do {
723+
try {
724+
return BitmapSampled(
725+
decoder!!.decodeRegion(rect, options),
726+
options.inSampleSize
727+
)
728+
} catch (e: OutOfMemoryError) {
729+
options.inSampleSize *= 2
730+
}
731+
} while (options.inSampleSize <= 512)
732+
} finally {
733+
decoder?.recycle()
740734
}
741-
} while (options.inSampleSize <= 512)
742-
743-
closeSafe(stream)
744-
decoder?.recycle()
735+
}
745736
} catch (e: Exception) {
746737
throw CropException.FailedToLoadBitmap(uri, e.message)
747738
}
@@ -934,19 +925,6 @@ internal object BitmapUtils {
934925
}
935926
}
936927

937-
/**
938-
* Close the given closeable object (Stream) in a safe way: check if it is null and catch-log
939-
* exception thrown.
940-
*
941-
* @param closeable the closable object to close
942-
*/
943-
private fun closeSafe(closeable: Closeable?) {
944-
try {
945-
closeable?.close()
946-
} catch (ignored: IOException) {
947-
}
948-
}
949-
950928
/**
951929
* Holds bitmap instance and the sample size that the bitmap was loaded/cropped with.
952930
*/

0 commit comments

Comments
 (0)