Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 949c6006 authored by Leon Scroggins III's avatar Leon Scroggins III
Browse files

Make bitmap compression retain the ColorSpace

Bug: 147877556
Test: I72b5f28903a67445bc205cdad8848384ad675b31

In Bitmap#compress and AndroidBitmap_compress, remove the conversion
from F16 to 8888 P3. This was originally done because F16 forced a
particular ColorSpace, and we wanted to use a wider gamut than SRGB.
Now that F16 can be any RGB ColorSpace, encode it with the ColorSpace
that it already has. Skip the conversion to 8888, which is unnecessary.
The encoders can already convert from F16.

Remove Bitmap::CompressResult. Now that compress does not allocate a
Bitmap, there is no reason to return ALLOCATION_FAILED.

Change-Id: I8190664398e762daf57092d919f382a56267dd07
parent 6e62dbb2
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -475,8 +475,7 @@ static jboolean Bitmap_compress(JNIEnv* env, jobject clazz, jlong bitmapHandle,
    }

    auto fm = static_cast<Bitmap::JavaCompressFormat>(format);
    auto result = bitmap->bitmap().compress(fm, quality, strm.get());
    return result == Bitmap::CompressResult::Success ? JNI_TRUE : JNI_FALSE;
    return bitmap->bitmap().compress(fm, quality, strm.get()) ? JNI_TRUE : JNI_FALSE;
}

static inline void bitmapErase(SkBitmap bitmap, const SkColor4f& color,
+2 −8
Original line number Diff line number Diff line
@@ -290,14 +290,8 @@ int ABitmap_compress(const AndroidBitmapInfo* info, ADataSpace dataSpace, const
    }

    CompressWriter stream(userContext, fn);
    switch (Bitmap::compress(bitmap, format, quality, &stream)) {
        case Bitmap::CompressResult::Success:
            return ANDROID_BITMAP_RESULT_SUCCESS;
        case Bitmap::CompressResult::AllocationFailed:
            return ANDROID_BITMAP_RESULT_ALLOCATION_FAILED;
        case Bitmap::CompressResult::Error:
            return ANDROID_BITMAP_RESULT_JNI_EXCEPTION;
    }
    return Bitmap::compress(bitmap, format, quality, &stream) ? ANDROID_BITMAP_RESULT_SUCCESS
                                                              : ANDROID_BITMAP_RESULT_JNI_EXCEPTION;
}

AHardwareBuffer* ABitmap_getHardwareBuffer(ABitmap* bitmapHandle) {
+5 −29
Original line number Diff line number Diff line
@@ -471,36 +471,14 @@ BitmapPalette Bitmap::computePalette(const SkImageInfo& info, const void* addr,
    return BitmapPalette::Unknown;
}

Bitmap::CompressResult Bitmap::compress(JavaCompressFormat format, int32_t quality,
                                        SkWStream* stream) {
bool Bitmap::compress(JavaCompressFormat format, int32_t quality, SkWStream* stream) {
    SkBitmap skbitmap;
    getSkBitmap(&skbitmap);
    return compress(skbitmap, format, quality, stream);
}

Bitmap::CompressResult Bitmap::compress(const SkBitmap& bitmap, JavaCompressFormat format,
bool Bitmap::compress(const SkBitmap& bitmap, JavaCompressFormat format,
                      int32_t quality, SkWStream* stream) {
    SkBitmap skbitmap = bitmap;
    if (skbitmap.colorType() == kRGBA_F16_SkColorType) {
        // Convert to P3 before encoding. This matches
        // SkAndroidCodec::computeOutputColorSpace for wide gamuts. Now that F16
        // could already be P3, we still want to convert to 8888.
        auto cs = SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, SkNamedGamut::kDCIP3);
        auto info = skbitmap.info().makeColorType(kRGBA_8888_SkColorType)
                                   .makeColorSpace(std::move(cs));
        SkBitmap p3;
        if (!p3.tryAllocPixels(info)) {
            return CompressResult::AllocationFailed;
        }

        SkPixmap pm;
        SkAssertResult(p3.peekPixels(&pm));  // should always work if tryAllocPixels() did.
        if (!skbitmap.readPixels(pm)) {
            return CompressResult::Error;
        }
        skbitmap = p3;
    }

    SkEncodedImageFormat fm;
    switch (format) {
        case JavaCompressFormat::Jpeg:
@@ -518,12 +496,10 @@ Bitmap::CompressResult Bitmap::compress(const SkBitmap& bitmap, JavaCompressForm
            options.fQuality = quality;
            options.fCompression = format == JavaCompressFormat::WebpLossy ?
                    SkWebpEncoder::Compression::kLossy : SkWebpEncoder::Compression::kLossless;
            return SkWebpEncoder::Encode(stream, skbitmap.pixmap(), options)
                    ? CompressResult::Success : CompressResult::Error;
            return SkWebpEncoder::Encode(stream, bitmap.pixmap(), options);
        }
    }

    return SkEncodeImage(stream, skbitmap, fm, quality)
            ? CompressResult::Success : CompressResult::Error;
    return SkEncodeImage(stream, bitmap, fm, quality);
}
}  // namespace android
+3 −9
Original line number Diff line number Diff line
@@ -154,15 +154,9 @@ public:
    WebpLossless = 4,
  };

  enum class CompressResult {
    Success,
    AllocationFailed,
    Error,
  };

  CompressResult compress(JavaCompressFormat format, int32_t quality, SkWStream* stream);
  bool compress(JavaCompressFormat format, int32_t quality, SkWStream* stream);

  static CompressResult compress(const SkBitmap& bitmap, JavaCompressFormat format,
  static bool compress(const SkBitmap& bitmap, JavaCompressFormat format,
                       int32_t quality, SkWStream* stream);
private:
    static sk_sp<Bitmap> allocateAshmemBitmap(size_t size, const SkImageInfo& i, size_t rowBytes);