Skip to content

Commit

Permalink
Auto-enable ultra HDR mode
Browse files Browse the repository at this point in the history
  • Loading branch information
saket committed Nov 28, 2024
1 parent b5ce155 commit 94b8350
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package me.saket.telephoto.subsamplingimage

import android.os.Build.VERSION.SDK_INT
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.Stable
Expand All @@ -10,6 +11,7 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.asAndroidBitmap
import androidx.compose.ui.graphics.painter.BitmapPainter
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.unit.IntSize
Expand All @@ -28,7 +30,6 @@ import me.saket.telephoto.subsamplingimage.internal.ImageSampleSize
import me.saket.telephoto.subsamplingimage.internal.ViewportImageTile
import me.saket.telephoto.subsamplingimage.internal.ViewportTile
import me.saket.telephoto.subsamplingimage.internal.calculateFor
import me.saket.telephoto.subsamplingimage.internal.contains
import me.saket.telephoto.subsamplingimage.internal.fastMapNotNull
import me.saket.telephoto.subsamplingimage.internal.generate
import me.saket.telephoto.subsamplingimage.internal.isNotEmpty
Expand Down Expand Up @@ -78,6 +79,13 @@ internal class RealSubSamplingImageState(
*/
private var loadedImages: ImmutableMap<ImageRegionTile, ImageDecodeResult> by mutableStateOf(persistentMapOf())

/**
* Whether the image contains [ultra HDR content](https://developer.android.com/media/grow/ultra-hdr/display).
*/
val hasUltraHdrContent: Boolean by derivedStateOf {
loadedImages.any { (_, result) -> result.hasUltraHdrContent } || imageSource.preview?.hasUltraHdrContent() == true
}

private val isReadyToBeDisplayed: Boolean by derivedStateOf {
val viewportSize = viewportSize
val imageSize = imageSize
Expand Down Expand Up @@ -164,4 +172,8 @@ internal class RealSubSamplingImageState(
}
}

private fun ImageBitmap.hasUltraHdrContent(): Boolean {
return if (SDK_INT >= 34) asAndroidBitmap().hasGainmap() else false
}

private fun ImageBitmap.size(): IntSize = IntSize(width, height)
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
package me.saket.telephoto.subsamplingimage

import android.annotation.SuppressLint
import android.content.pm.ActivityInfo
import android.os.Build.VERSION.SDK_INT
import androidx.compose.foundation.layout.Box
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.Stable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawBehind
Expand All @@ -16,6 +19,7 @@ import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.graphics.drawscope.withTransform
import androidx.compose.ui.layout.layout
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.role
Expand All @@ -30,6 +34,7 @@ import androidx.compose.ui.unit.toSize
import androidx.compose.ui.util.fastForEach
import me.saket.telephoto.subsamplingimage.internal.SubSamplingImageSemanticState
import me.saket.telephoto.subsamplingimage.internal.ViewportImageTile
import me.saket.telephoto.subsamplingimage.internal.findActivity
import me.saket.telephoto.subsamplingimage.internal.imageSemanticState
import me.saket.telephoto.subsamplingimage.internal.toCeilInt

Expand Down Expand Up @@ -85,6 +90,18 @@ fun SubSamplingImage(
)
}
)

if (state.hasUltraHdrContent && SDK_INT >= 26) {
val context = LocalContext.current
DisposableEffect(Unit) {
val activity = context.findActivity()
val previousColorMode = activity.window.colorMode
activity.window.colorMode = ActivityInfo.COLOR_MODE_HDR
onDispose {
activity.window.colorMode = previousColorMode
}
}
}
}

private fun DrawScope.drawImageTile(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package me.saket.telephoto.subsamplingimage.internal

import android.app.Activity
import android.content.Context
import android.content.ContextWrapper

// todo: delete this when LocalActivity is available in androidx.activity.
internal tailrec fun Context.findActivity(): Activity {
return when (this) {
is Activity -> this
is ContextWrapper -> this.baseContext.findActivity()
else -> throw IllegalArgumentException("Could not find activity!")
}
}

0 comments on commit 94b8350

Please sign in to comment.