Use dynamic quality and webp for archive thumbnail generation.

This commit is contained in:
Cody Henthorne
2025-06-04 11:05:51 -04:00
parent e3ee3d3dba
commit be4af1d560
5 changed files with 54 additions and 7 deletions

View File

@@ -59,7 +59,7 @@ public final class ImageCompressionUtil {
@IntRange(from = 0, to = 100) int quality)
throws BitmapDecodingException
{
Result result = compress(context, mimeType, glideModel, maxDimension, quality);
Result result = compress(context, mimeType, mimeType, glideModel, maxDimension, quality);
if (result.getData().length <= maxBytes) {
return result;
@@ -74,6 +74,7 @@ public final class ImageCompressionUtil {
@WorkerThread
public static @NonNull Result compress(@NonNull Context context,
@Nullable String contentType,
@Nullable String targetContentType,
@NonNull Object glideModel,
int maxDimension,
@IntRange(from = 0, to = 100) int quality)
@@ -121,7 +122,7 @@ public final class ImageCompressionUtil {
}
ByteArrayOutputStream output = new ByteArrayOutputStream();
Bitmap.CompressFormat format = mimeTypeToCompressFormat(contentType);
Bitmap.CompressFormat format = mimeTypeToCompressFormat(targetContentType);
scaledBitmap.compress(format, quality, output);
byte[] data = output.toByteArray();
@@ -137,6 +138,8 @@ public final class ImageCompressionUtil {
MediaUtil.isAvifType(mimeType) ||
MediaUtil.isVideoType(mimeType)) {
return Bitmap.CompressFormat.JPEG;
} else if (MediaUtil.isWebpType(mimeType)) {
return Bitmap.CompressFormat.WEBP;
} else {
return Bitmap.CompressFormat.PNG;
}
@@ -148,6 +151,8 @@ public final class ImageCompressionUtil {
return MediaUtil.IMAGE_JPEG;
case PNG:
return MediaUtil.IMAGE_PNG;
case WEBP:
return MediaUtil.IMAGE_WEBP;
default:
throw new AssertionError("Unsupported format!");
}

View File

@@ -347,6 +347,10 @@ public class MediaUtil {
return !TextUtils.isEmpty(contentType) && contentType.trim().equals(IMAGE_AVIF);
}
public static boolean isWebpType(String contentType) {
return !TextUtils.isEmpty(contentType) && contentType.trim().equals(IMAGE_WEBP);
}
public static boolean isFile(Attachment attachment) {
return !isGif(attachment) && !isImage(attachment) && !isAudio(attachment) && !isVideo(attachment);
}

View File

@@ -5,7 +5,10 @@ import androidx.annotation.VisibleForTesting
import androidx.annotation.WorkerThread
import org.json.JSONException
import org.json.JSONObject
import org.signal.core.util.ByteSize
import org.signal.core.util.bytes
import org.signal.core.util.gibiBytes
import org.signal.core.util.kibiBytes
import org.signal.core.util.logging.Log
import org.signal.core.util.mebiBytes
import org.thoughtcrime.securesms.BuildConfig
@@ -989,6 +992,15 @@ object RemoteConfig {
defaultValue = 3
)
/** Max plaintext unpadded file size for backup thumbnails. */
val backupMaxThumbnailFileSize: ByteSize by remoteValue(
key = "global.backups.maxThumbnailFileSizeBytes",
hotSwappable = true,
active = true
) { value ->
value.asLong(8.kibiBytes.inWholeBytes).bytes
}
/** Whether unauthenticated chat web socket is backed by libsignal-net */
@JvmStatic
@get:JvmName("libSignalWebSocketEnabled")