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
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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,
|
||||
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;
|
||||
}
|
||||
|
||||
bool Bitmap::compress(const SkBitmap& bitmap, JavaCompressFormat format,
|
||||
int32_t quality, SkWStream* stream) {
|
||||
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
|
||||
|
||||
@@ -154,16 +154,10 @@ public:
|
||||
WebpLossless = 4,
|
||||
};
|
||||
|
||||
enum class CompressResult {
|
||||
Success,
|
||||
AllocationFailed,
|
||||
Error,
|
||||
};
|
||||
bool compress(JavaCompressFormat format, int32_t quality, SkWStream* stream);
|
||||
|
||||
CompressResult compress(JavaCompressFormat format, int32_t quality, SkWStream* stream);
|
||||
|
||||
static CompressResult compress(const SkBitmap& bitmap, JavaCompressFormat format,
|
||||
int32_t quality, SkWStream* stream);
|
||||
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);
|
||||
static sk_sp<Bitmap> allocateHeapBitmap(size_t size, const SkImageInfo& i, size_t rowBytes);
|
||||
|
||||
Reference in New Issue
Block a user