Skip to content

Commit

Permalink
Move imageChecks.kt out of the internal package
Browse files Browse the repository at this point in the history
  • Loading branch information
saket committed Dec 7, 2024
1 parent 86939af commit 74ff742
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.withContext
import me.saket.telephoto.subsamplingimage.ImageBitmapOptions
import me.saket.telephoto.subsamplingimage.SubSamplingImageSource
import me.saket.telephoto.subsamplingimage.internal.canBeSubSampled
import me.saket.telephoto.subsamplingimage.internal.exists
import me.saket.telephoto.subsamplingimage.util.canBeSubSampled
import me.saket.telephoto.subsamplingimage.util.exists
import me.saket.telephoto.zoomable.ZoomableImageSource
import me.saket.telephoto.zoomable.ZoomableImageSource.ResolveResult
import me.saket.telephoto.zoomable.coil.Resolver.ImageSourceCreationResult.EligibleForSubSampling
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.withContext
import me.saket.telephoto.subsamplingimage.ImageBitmapOptions
import me.saket.telephoto.subsamplingimage.SubSamplingImageSource
import me.saket.telephoto.subsamplingimage.internal.canBeSubSampled
import me.saket.telephoto.subsamplingimage.internal.exists
import me.saket.telephoto.subsamplingimage.util.canBeSubSampled
import me.saket.telephoto.subsamplingimage.util.exists
import me.saket.telephoto.zoomable.ZoomableImageSource
import me.saket.telephoto.zoomable.ZoomableImageSource.ResolveResult
import me.saket.telephoto.zoomable.coil3.Resolver.ImageSourceCreationResult.EligibleForSubSampling
Expand Down
9 changes: 9 additions & 0 deletions zoomable-image/sub-sampling-image/api/api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,15 @@ package me.saket.telephoto.subsamplingimage {

package me.saket.telephoto.subsamplingimage.internal {

public final class ImageChecksKt {
method @Deprecated public static suspend Object? canBeSubSampled(me.saket.telephoto.subsamplingimage.SubSamplingImageSource, android.content.Context context, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
method @Deprecated public static suspend Object? exists(me.saket.telephoto.subsamplingimage.SubSamplingImageSource, android.content.Context context, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
}

}

package me.saket.telephoto.subsamplingimage.util {

public final class ImageChecksKt {
method public static suspend Object? canBeSubSampled(me.saket.telephoto.subsamplingimage.SubSamplingImageSource, android.content.Context context, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
method public static suspend Object? exists(me.saket.telephoto.subsamplingimage.SubSamplingImageSource, android.content.Context context, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,49 +1,26 @@
package me.saket.telephoto.subsamplingimage.internal

import android.content.Context
import android.util.TypedValue
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import me.saket.telephoto.subsamplingimage.ResourceImageSource
import me.saket.telephoto.subsamplingimage.SubSamplingImageSource
import okio.Buffer
import me.saket.telephoto.subsamplingimage.util.canBeSubSampled as canBeSubSampledV2
import me.saket.telephoto.subsamplingimage.util.exists as existsV2

/**
* Check whether an image source can be sub-sampled and decoded using [AndroidImageRegionDecoder].
*/
@Deprecated(
message = "Moved to another package",
replaceWith = ReplaceWith("canBeSubSampled(context)", "me.saket.telephoto.subsamplingimage.util.canBeSubSampled")
)
suspend fun SubSamplingImageSource.canBeSubSampled(context: Context): Boolean {
if (this is ResourceImageSource) {
return !isVectorDrawable(context)
}

return withContext(Dispatchers.IO) {
peek(context).use {
// Check for GIFs as well because Android's ImageDecoder
// can return a Bitmap for single-frame GIFs.
!isSvg(it) && !isGif(it)
}
}
return canBeSubSampledV2(context)
}

/** Check whether an image source exists and has non-zero bytes. */
@Deprecated(
message = "Moved to another package",
replaceWith = ReplaceWith("exists(context)", "me.saket.telephoto.subsamplingimage.util.exists")
)
suspend fun SubSamplingImageSource.exists(context: Context): Boolean {
return withContext(Dispatchers.IO) {
try {
peek(context).read(Buffer(), byteCount = 1) != -1L
} catch (e: okio.FileNotFoundException) {
// This catch block currently makes an assumption that files are only read
// using okio, which is true for SubSamplingImageSource.file(), but might
// fail for SubSamplingImageSource.rawSource(). I could probably make exists()
// a member function of SubSamplingImageSource to fix that.
false
}
}
}

private suspend fun ResourceImageSource.isVectorDrawable(context: Context): Boolean {
return withContext(Dispatchers.IO) {
TypedValue().apply {
context.resources.getValue(id, this, /* resolveRefs = */ true)
}.string.endsWith(".xml")
}
return existsV2(context)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package me.saket.telephoto.subsamplingimage.util

import android.content.Context
import android.util.TypedValue
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import me.saket.telephoto.subsamplingimage.ResourceImageSource
import me.saket.telephoto.subsamplingimage.SubSamplingImageSource
import me.saket.telephoto.subsamplingimage.internal.AndroidImageRegionDecoder
import me.saket.telephoto.subsamplingimage.internal.isGif
import me.saket.telephoto.subsamplingimage.internal.isSvg
import okio.Buffer

/**
* Check whether an image source can be sub-sampled and decoded using [AndroidImageRegionDecoder].
*/
suspend fun SubSamplingImageSource.canBeSubSampled(context: Context): Boolean {
if (this is ResourceImageSource) {
return !isVectorDrawable(context)
}

return withContext(Dispatchers.IO) {
peek(context).use {
// Check for GIFs as well because Android's ImageDecoder
// can return a Bitmap for single-frame GIFs.
!isSvg(it) && !isGif(it)
}
}
}

/** Check whether an image source exists and has non-zero bytes. */
suspend fun SubSamplingImageSource.exists(context: Context): Boolean {
return withContext(Dispatchers.IO) {
try {
peek(context).read(Buffer(), byteCount = 1) != -1L
} catch (e: okio.FileNotFoundException) {
// This catch block currently makes an assumption that files are only read
// using okio, which is true for SubSamplingImageSource.file(), but might
// fail for SubSamplingImageSource.rawSource(). I could probably make exists()
// a member function of SubSamplingImageSource to fix that.
false
}
}
}

private suspend fun ResourceImageSource.isVectorDrawable(context: Context): Boolean {
return withContext(Dispatchers.IO) {
TypedValue().apply {
context.resources.getValue(id, this, /* resolveRefs = */ true)
}.string.endsWith(".xml")
}
}

0 comments on commit 74ff742

Please sign in to comment.