Skip to content

Commit

Permalink
Clean up preserveGainmapAndColorSpaceForTransformations flag
Browse files Browse the repository at this point in the history
  • Loading branch information
falhassen authored and kanelbulle committed Feb 13, 2024
1 parent fcace5b commit 193cf61
Show file tree
Hide file tree
Showing 6 changed files with 20 additions and 128 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -562,12 +562,7 @@ private static Downsampler buildDownsamplerWithGainmapBugFixes() {
BitmapPool bitmapPool = new BitmapPoolAdapter();
ArrayPool arrayPool = new LruArrayPool();
return new Downsampler(
parsers,
displayMetrics,
bitmapPool,
arrayPool,
/* preserveGainmapAndColorSpaceForTransformations= */ true,
/* enableHardwareGainmapFixOnU= */ true);
parsers, displayMetrics, bitmapPool, arrayPool, /* enableHardwareGainmapFixOnU= */ true);
}

private static InputStream openBitmapStream(
Expand Down
15 changes: 3 additions & 12 deletions library/src/main/java/com/bumptech/glide/GlideBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -488,14 +488,11 @@ public GlideBuilder setImageDecoderEnabledForBitmaps(boolean isEnabled) {
}

/**
* Preserves gainmap and color spaces while {@link Bitmap}s undergo transformation, i.e., in
* {@link com.bumptech.glide.load.resource.bitmap.TransformationUtils}.
*
* <p>Without this flag on, gainmap and color space information may be dropped in transformations,
* leading to unexpected behavior when transforming wide gamut images or Ultra HDR images.
* @deprecated This method does nothing. It will be hard coded and removed in a future release
* without further warning.
*/
@Deprecated
public GlideBuilder setPreserveGainmapAndColorSpaceForTransformations(boolean isEnabled) {
glideExperimentsBuilder.update(new PreserveGainmapAndColorSpaceForTransformations(), isEnabled);
return this;
}

Expand Down Expand Up @@ -623,12 +620,6 @@ static final class ManualOverrideHardwareBitmapMaxFdCount implements Experiment
}
}

/**
* Preserves gainmap and color spaces while {@link Bitmap}s undergo transformation, i.e., in
* {@link com.bumptech.glide.load.resource.bitmap.TransformationUtils}.
*/
static final class PreserveGainmapAndColorSpaceForTransformations implements Experiment {}

/** Fixes decoding of hardware gainmaps from Ultra HDR images on Android U. */
static final class EnableHardwareGainmapFixOnU implements Experiment {}

Expand Down
2 changes: 0 additions & 2 deletions library/src/main/java/com/bumptech/glide/RegistryFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import androidx.tracing.Trace;
import com.bumptech.glide.GlideBuilder.EnableHardwareGainmapFixOnU;
import com.bumptech.glide.GlideBuilder.EnableImageDecoderForBitmaps;
import com.bumptech.glide.GlideBuilder.PreserveGainmapAndColorSpaceForTransformations;
import com.bumptech.glide.gifdecoder.GifDecoder;
import com.bumptech.glide.load.ImageHeaderParser;
import com.bumptech.glide.load.ResourceDecoder;
Expand Down Expand Up @@ -161,7 +160,6 @@ private static void initializeDefaults(
resources.getDisplayMetrics(),
bitmapPool,
arrayPool,
experiments.isEnabled(PreserveGainmapAndColorSpaceForTransformations.class),
experiments.isEnabled(EnableHardwareGainmapFixOnU.class));

ResourceDecoder<ByteBuffer, Bitmap> byteBufferBitmapDecoder;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,6 @@ public void onDecodeComplete(BitmapPool bitmapPool, Bitmap downsampled) {
private final ArrayPool byteArrayPool;
private final List<ImageHeaderParser> parsers;
private final HardwareConfigState hardwareConfigState = HardwareConfigState.getInstance();
private final boolean preserveGainmapAndColorSpaceForTransformations;
private final boolean enableHardwareGainmapFixOnU;

public Downsampler(
Expand All @@ -154,49 +153,22 @@ public Downsampler(
displayMetrics,
bitmapPool,
byteArrayPool,
/* preserveGainmapAndColorSpaceForTransformations= */ false,
/* enableHardwareGainmapFixOnU= */ false);
}

/**
* @param preserveGainmapAndColorSpaceForTransformations Preserves gainmap and color space for
* transformation, e.g., the color space of wide gamut images or the gainmap of Ultra HDR
* images.
*/
public Downsampler(
List<ImageHeaderParser> parsers,
DisplayMetrics displayMetrics,
BitmapPool bitmapPool,
ArrayPool byteArrayPool,
boolean preserveGainmapAndColorSpaceForTransformations) {
this(
parsers,
displayMetrics,
bitmapPool,
byteArrayPool,
preserveGainmapAndColorSpaceForTransformations,
/* enableHardwareGainmapFixOnU= */ false);
}

/**
* @param preserveGainmapAndColorSpaceForTransformations Preserves gainmap and color space for
* transformation, e.g., the color space of wide gamut images or the gainmap of Ultra HDR
* images.
* @param enableHardwareGainmapFixOnU Fixes issues with hardware gainmaps on U.
*/
public Downsampler(
List<ImageHeaderParser> parsers,
DisplayMetrics displayMetrics,
BitmapPool bitmapPool,
ArrayPool byteArrayPool,
boolean preserveGainmapAndColorSpaceForTransformations,
boolean enableHardwareGainmapFixOnU) {
this.parsers = parsers;
this.displayMetrics = Preconditions.checkNotNull(displayMetrics);
this.bitmapPool = Preconditions.checkNotNull(bitmapPool);
this.byteArrayPool = Preconditions.checkNotNull(byteArrayPool);
this.preserveGainmapAndColorSpaceForTransformations =
preserveGainmapAndColorSpaceForTransformations;
this.enableHardwareGainmapFixOnU = enableHardwareGainmapFixOnU;
}

Expand Down Expand Up @@ -498,9 +470,7 @@ private Bitmap decodeFromWrappedStreams(
// the expected density dpi.
downsampled.setDensity(displayMetrics.densityDpi);

rotated =
TransformationUtils.rotateImageExif(
bitmapPool, downsampled, orientation, preserveGainmapAndColorSpaceForTransformations);
rotated = TransformationUtils.rotateImageExif(bitmapPool, downsampled, orientation);
if (!downsampled.equals(rotated)) {
bitmapPool.put(downsampled);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -304,73 +304,30 @@ public static int getExifOrientationDegrees(int exifOrientation) {
/**
* Rotate and/or flip the image to match the given exif orientation.
*
* <p>Note that this method will not preserve the image's color gamut and gainmap. Use {@link
* #rotateImageExif(BitmapPool, Bitmap, int, boolean)} to enable that functionality.
*
* @param pool A pool that may or may not contain an image of the necessary dimensions.
* @param inBitmap The bitmap to rotate/flip.
* @param exifOrientation the exif orientation [1-8].
* @return The rotated and/or flipped image or toOrient if no rotation or flip was necessary.
*/
public static Bitmap rotateImageExif(
@NonNull BitmapPool pool, @NonNull Bitmap inBitmap, int exifOrientation) {
return rotateImageExif(
pool, inBitmap, exifOrientation, /* preserveGainmapAndColorSpace= */ false);
}

/**
* Rotate and/or flip the image to match the given exif orientation.
*
* @param pool A pool that may or may not contain an image of the necessary dimensions.
* @param inBitmap The bitmap to rotate/flip.
* @param exifOrientation the exif orientation [1-8].
* @param preserveGainmapAndColorSpace whether to preserve gainmap and color space information
* post-transformation.
* @return The rotated and/or flipped image or inBitmap if no rotation or flip was necessary.
*/
public static Bitmap rotateImageExif(
@NonNull BitmapPool pool,
@NonNull Bitmap inBitmap,
int exifOrientation,
boolean preserveGainmapAndColorSpace) {
if (!isExifOrientationRequired(exifOrientation)) {
return inBitmap;
}

final Matrix matrix = new Matrix();
initializeMatrixForRotation(exifOrientation, matrix);

Bitmap result;
if (preserveGainmapAndColorSpace) {
// BitmapPool doesn't preserve gainmaps and color space, so use Bitmap.create to apply the
// matrix.
result =
Bitmap.createBitmap(
inBitmap,
/* x= */ 0,
/* y= */ 0,
inBitmap.getWidth(),
inBitmap.getHeight(),
matrix,
/* filter= */ true);
} else {
// From Bitmap.createBitmap.
final RectF newRect = new RectF(0, 0, inBitmap.getWidth(), inBitmap.getHeight());
matrix.mapRect(newRect);

final int newWidth = Math.round(newRect.width());
final int newHeight = Math.round(newRect.height());

Bitmap.Config config = getNonNullConfig(inBitmap);
result = pool.get(newWidth, newHeight, config);

matrix.postTranslate(-newRect.left, -newRect.top);

result.setHasAlpha(inBitmap.hasAlpha());

applyMatrix(inBitmap, result, matrix);
}
return result;
// BitmapPool doesn't preserve gainmaps and color space, so use Bitmap.create to apply the
// matrix.
return Bitmap.createBitmap(
inBitmap,
/* x= */ 0,
/* y= */ 0,
inBitmap.getWidth(),
inBitmap.getHeight(),
matrix,
/* filter= */ true);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
Expand All @@ -15,7 +16,6 @@
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.ColorSpace;
import android.graphics.ColorSpace.Named;
import android.graphics.Matrix;
import android.os.Build.VERSION_CODES;
import androidx.exifinterface.media.ExifInterface;
Expand Down Expand Up @@ -403,43 +403,24 @@ public void testRotateImageExifReturnsGivenBitmapIfOrientationIsInvalid() {

@Test
@Config(sdk = 19)
public void testRotateImageExifHandlesBitmapsWithNullConfigs() {
public void testRotateImageExif_preservesitmapsWithNullConfigs() {
Bitmap toRotate = Bitmap.createBitmap(100, 100, Bitmap.Config.RGB_565);
toRotate.setConfig(null);
Bitmap rotated =
TransformationUtils.rotateImageExif(
bitmapPool, toRotate, ExifInterface.ORIENTATION_ROTATE_180);
assertEquals(Bitmap.Config.ARGB_8888, rotated.getConfig());
assertNull(rotated.getConfig());
}

@Test
@Config(sdk = VERSION_CODES.UPSIDE_DOWN_CAKE)
public void rotateImageExif_flagOff_doesNotPreserveColorSpace() {
public void rotateImageExif_preservesColorSpace() {
Bitmap toRotate = Bitmap.createBitmap(200, 100, Bitmap.Config.ARGB_8888);
toRotate.setColorSpace(ColorSpace.get(ColorSpace.Named.DISPLAY_P3));

Bitmap rotated =
TransformationUtils.rotateImageExif(
bitmapPool,
toRotate,
ExifInterface.ORIENTATION_ROTATE_90,
/* preserveGainmapAndColorSpace= */ false);

assertEquals(ColorSpace.get(Named.SRGB), rotated.getColorSpace());
}

@Test
@Config(sdk = VERSION_CODES.UPSIDE_DOWN_CAKE)
public void rotateImageExif_flagOm_preservesColorSpace() {
Bitmap toRotate = Bitmap.createBitmap(200, 100, Bitmap.Config.ARGB_8888);
toRotate.setColorSpace(ColorSpace.get(ColorSpace.Named.DISPLAY_P3));

Bitmap rotated =
TransformationUtils.rotateImageExif(
bitmapPool,
toRotate,
ExifInterface.ORIENTATION_ROTATE_90,
/* preserveGainmapAndColorSpace= */ true);
bitmapPool, toRotate, ExifInterface.ORIENTATION_ROTATE_90);

assertEquals(ColorSpace.get(ColorSpace.Named.DISPLAY_P3), rotated.getColorSpace());
}
Expand Down

0 comments on commit 193cf61

Please sign in to comment.