Loading core/jni/android/graphics/apex/android_bitmap.cpp +1 −89 Original line number Diff line number Diff line Loading @@ -123,98 +123,10 @@ AndroidBitmapInfo ABitmap_getInfo(ABitmap* bitmapHandle) { return getInfo(bitmap->info(), bitmap->rowBytes()); } namespace { static bool nearlyEqual(float a, float b) { // By trial and error, this is close enough to match for the ADataSpaces we // compare for. return ::fabs(a - b) < .002f; } static bool nearlyEqual(const skcms_TransferFunction& x, const skcms_TransferFunction& y) { return nearlyEqual(x.g, y.g) && nearlyEqual(x.a, y.a) && nearlyEqual(x.b, y.b) && nearlyEqual(x.c, y.c) && nearlyEqual(x.d, y.d) && nearlyEqual(x.e, y.e) && nearlyEqual(x.f, y.f); } static bool nearlyEqual(const skcms_Matrix3x3& x, const skcms_Matrix3x3& y) { for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (!nearlyEqual(x.vals[i][j], y.vals[i][j])) return false; } } return true; } static constexpr skcms_TransferFunction k2Dot6 = {2.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}; // Skia's SkNamedGamut::kDCIP3 is based on a white point of D65. This gamut // matches the white point used by ColorSpace.Named.DCIP3. static constexpr skcms_Matrix3x3 kDCIP3 = {{ {0.486143, 0.323835, 0.154234}, {0.226676, 0.710327, 0.0629966}, {0.000800549, 0.0432385, 0.78275}, }}; } // anonymous namespace ADataSpace ABitmap_getDataSpace(ABitmap* bitmapHandle) { Bitmap* bitmap = TypeCast::toBitmap(bitmapHandle); const SkImageInfo& info = bitmap->info(); SkColorSpace* colorSpace = info.colorSpace(); if (!colorSpace) { return ADATASPACE_UNKNOWN; } if (colorSpace->isSRGB()) { if (info.colorType() == kRGBA_F16_SkColorType) { return ADATASPACE_SCRGB; } return ADATASPACE_SRGB; } skcms_TransferFunction fn; LOG_ALWAYS_FATAL_IF(!colorSpace->isNumericalTransferFn(&fn)); skcms_Matrix3x3 gamut; LOG_ALWAYS_FATAL_IF(!colorSpace->toXYZD50(&gamut)); if (nearlyEqual(gamut, SkNamedGamut::kSRGB)) { if (nearlyEqual(fn, SkNamedTransferFn::kLinear)) { // Skia doesn't differentiate amongst the RANGES. In Java, we associate // LINEAR_EXTENDED_SRGB with F16, and LINEAR_SRGB with other Configs. // Make the same association here. if (info.colorType() == kRGBA_F16_SkColorType) { return ADATASPACE_SCRGB_LINEAR; } return ADATASPACE_SRGB_LINEAR; } if (nearlyEqual(fn, SkNamedTransferFn::kRec2020)) { return ADATASPACE_BT709; } } if (nearlyEqual(fn, SkNamedTransferFn::kSRGB) && nearlyEqual(gamut, SkNamedGamut::kDCIP3)) { return ADATASPACE_DISPLAY_P3; } if (nearlyEqual(fn, SkNamedTransferFn::k2Dot2) && nearlyEqual(gamut, SkNamedGamut::kAdobeRGB)) { return ADATASPACE_ADOBE_RGB; } if (nearlyEqual(fn, SkNamedTransferFn::kRec2020) && nearlyEqual(gamut, SkNamedGamut::kRec2020)) { return ADATASPACE_BT2020; } if (nearlyEqual(fn, k2Dot6) && nearlyEqual(gamut, kDCIP3)) { return ADATASPACE_DCI_P3; } return ADATASPACE_UNKNOWN; return (ADataSpace)uirenderer::ColorSpaceToADataSpace(info.colorSpace(), info.colorType()); } AndroidBitmapInfo ABitmap_getInfoFromJava(JNIEnv* env, jobject bitmapObj) { Loading libs/hwui/utils/Color.cpp +86 −3 Original line number Diff line number Diff line Loading @@ -108,7 +108,9 @@ SkColorType PixelFormatToColorType(android::PixelFormat format) { } } // FIXME: Share with the version in android_bitmap.cpp? namespace { static constexpr skcms_TransferFunction k2Dot6 = {2.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}; // Skia's SkNamedGamut::kDCIP3 is based on a white point of D65. This gamut // matches the white point used by ColorSpace.Named.DCIP3. static constexpr skcms_Matrix3x3 kDCIP3 = {{ Loading @@ -117,6 +119,87 @@ static constexpr skcms_Matrix3x3 kDCIP3 = {{ {0.000800549, 0.0432385, 0.78275}, }}; static bool nearlyEqual(float a, float b) { // By trial and error, this is close enough to match for the ADataSpaces we // compare for. return ::fabs(a - b) < .002f; } static bool nearlyEqual(const skcms_TransferFunction& x, const skcms_TransferFunction& y) { return nearlyEqual(x.g, y.g) && nearlyEqual(x.a, y.a) && nearlyEqual(x.b, y.b) && nearlyEqual(x.c, y.c) && nearlyEqual(x.d, y.d) && nearlyEqual(x.e, y.e) && nearlyEqual(x.f, y.f); } static bool nearlyEqual(const skcms_Matrix3x3& x, const skcms_Matrix3x3& y) { for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (!nearlyEqual(x.vals[i][j], y.vals[i][j])) return false; } } return true; } } // anonymous namespace android_dataspace ColorSpaceToADataSpace(SkColorSpace* colorSpace, SkColorType colorType) { if (!colorSpace) { return HAL_DATASPACE_UNKNOWN; } if (colorSpace->isSRGB()) { if (colorType == kRGBA_F16_SkColorType) { return HAL_DATASPACE_V0_SCRGB; } return HAL_DATASPACE_V0_SRGB; } skcms_TransferFunction fn; LOG_ALWAYS_FATAL_IF(!colorSpace->isNumericalTransferFn(&fn)); skcms_Matrix3x3 gamut; LOG_ALWAYS_FATAL_IF(!colorSpace->toXYZD50(&gamut)); if (nearlyEqual(gamut, SkNamedGamut::kSRGB)) { if (nearlyEqual(fn, SkNamedTransferFn::kLinear)) { // Skia doesn't differentiate amongst the RANGES. In Java, we associate // LINEAR_EXTENDED_SRGB with F16, and LINEAR_SRGB with other Configs. // Make the same association here. if (colorType == kRGBA_F16_SkColorType) { return HAL_DATASPACE_V0_SCRGB_LINEAR; } return HAL_DATASPACE_V0_SRGB_LINEAR; } if (nearlyEqual(fn, SkNamedTransferFn::kRec2020)) { return HAL_DATASPACE_V0_BT709; } } if (nearlyEqual(fn, SkNamedTransferFn::kSRGB) && nearlyEqual(gamut, SkNamedGamut::kDCIP3)) { return HAL_DATASPACE_DISPLAY_P3; } if (nearlyEqual(fn, SkNamedTransferFn::k2Dot2) && nearlyEqual(gamut, SkNamedGamut::kAdobeRGB)) { return HAL_DATASPACE_ADOBE_RGB; } if (nearlyEqual(fn, SkNamedTransferFn::kRec2020) && nearlyEqual(gamut, SkNamedGamut::kRec2020)) { return HAL_DATASPACE_BT2020; } if (nearlyEqual(fn, k2Dot6) && nearlyEqual(gamut, kDCIP3)) { return HAL_DATASPACE_DCI_P3; } return HAL_DATASPACE_UNKNOWN; } sk_sp<SkColorSpace> DataSpaceToColorSpace(android_dataspace dataspace) { if (dataspace == HAL_DATASPACE_UNKNOWN) { return SkColorSpace::MakeSRGB(); Loading @@ -126,7 +209,7 @@ sk_sp<SkColorSpace> DataSpaceToColorSpace(android_dataspace dataspace) { // needs to use the locally-defined kDCIP3 gamut, rather than the one in // Skia (SkNamedGamut), which is used for other data spaces with // HAL_DATASPACE_STANDARD_DCI_P3 (e.g. HAL_DATASPACE_DISPLAY_P3). return SkColorSpace::MakeRGB({2.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, kDCIP3); return SkColorSpace::MakeRGB(k2Dot6, kDCIP3); } skcms_Matrix3x3 gamut; Loading Loading @@ -165,7 +248,7 @@ sk_sp<SkColorSpace> DataSpaceToColorSpace(android_dataspace dataspace) { case HAL_DATASPACE_TRANSFER_GAMMA2_2: return SkColorSpace::MakeRGB({2.2f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, gamut); case HAL_DATASPACE_TRANSFER_GAMMA2_6: return SkColorSpace::MakeRGB({2.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, gamut); return SkColorSpace::MakeRGB(k2Dot6, gamut); case HAL_DATASPACE_TRANSFER_GAMMA2_8: return SkColorSpace::MakeRGB({2.8f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, gamut); case HAL_DATASPACE_TRANSFER_ST2084: Loading libs/hwui/utils/Color.h +16 −0 Original line number Diff line number Diff line Loading @@ -105,6 +105,22 @@ ANDROID_API SkColorType PixelFormatToColorType(android::PixelFormat format); ANDROID_API sk_sp<SkColorSpace> DataSpaceToColorSpace(android_dataspace dataspace); /** * Return the android_dataspace corresponding to colorSpace. * * Note: This currently only returns android_dataspaces with corresponding * ADataSpaces. The NDK relies on this, so if you need to update it to return * an android_dataspace *without* an ADataSpace, the NDK methods need to be * updated. * * @param colorSpace May be null, in which case this will return * HAL_DATASPACE_UNKNOWN. * @param colorType Some SkColorSpaces are associated with more than one * android_dataspace. In that case, the SkColorType is used to * determine which one to return. */ ANDROID_API android_dataspace ColorSpaceToADataSpace(SkColorSpace*, SkColorType); struct Lab { float L; float a; Loading Loading
core/jni/android/graphics/apex/android_bitmap.cpp +1 −89 Original line number Diff line number Diff line Loading @@ -123,98 +123,10 @@ AndroidBitmapInfo ABitmap_getInfo(ABitmap* bitmapHandle) { return getInfo(bitmap->info(), bitmap->rowBytes()); } namespace { static bool nearlyEqual(float a, float b) { // By trial and error, this is close enough to match for the ADataSpaces we // compare for. return ::fabs(a - b) < .002f; } static bool nearlyEqual(const skcms_TransferFunction& x, const skcms_TransferFunction& y) { return nearlyEqual(x.g, y.g) && nearlyEqual(x.a, y.a) && nearlyEqual(x.b, y.b) && nearlyEqual(x.c, y.c) && nearlyEqual(x.d, y.d) && nearlyEqual(x.e, y.e) && nearlyEqual(x.f, y.f); } static bool nearlyEqual(const skcms_Matrix3x3& x, const skcms_Matrix3x3& y) { for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (!nearlyEqual(x.vals[i][j], y.vals[i][j])) return false; } } return true; } static constexpr skcms_TransferFunction k2Dot6 = {2.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}; // Skia's SkNamedGamut::kDCIP3 is based on a white point of D65. This gamut // matches the white point used by ColorSpace.Named.DCIP3. static constexpr skcms_Matrix3x3 kDCIP3 = {{ {0.486143, 0.323835, 0.154234}, {0.226676, 0.710327, 0.0629966}, {0.000800549, 0.0432385, 0.78275}, }}; } // anonymous namespace ADataSpace ABitmap_getDataSpace(ABitmap* bitmapHandle) { Bitmap* bitmap = TypeCast::toBitmap(bitmapHandle); const SkImageInfo& info = bitmap->info(); SkColorSpace* colorSpace = info.colorSpace(); if (!colorSpace) { return ADATASPACE_UNKNOWN; } if (colorSpace->isSRGB()) { if (info.colorType() == kRGBA_F16_SkColorType) { return ADATASPACE_SCRGB; } return ADATASPACE_SRGB; } skcms_TransferFunction fn; LOG_ALWAYS_FATAL_IF(!colorSpace->isNumericalTransferFn(&fn)); skcms_Matrix3x3 gamut; LOG_ALWAYS_FATAL_IF(!colorSpace->toXYZD50(&gamut)); if (nearlyEqual(gamut, SkNamedGamut::kSRGB)) { if (nearlyEqual(fn, SkNamedTransferFn::kLinear)) { // Skia doesn't differentiate amongst the RANGES. In Java, we associate // LINEAR_EXTENDED_SRGB with F16, and LINEAR_SRGB with other Configs. // Make the same association here. if (info.colorType() == kRGBA_F16_SkColorType) { return ADATASPACE_SCRGB_LINEAR; } return ADATASPACE_SRGB_LINEAR; } if (nearlyEqual(fn, SkNamedTransferFn::kRec2020)) { return ADATASPACE_BT709; } } if (nearlyEqual(fn, SkNamedTransferFn::kSRGB) && nearlyEqual(gamut, SkNamedGamut::kDCIP3)) { return ADATASPACE_DISPLAY_P3; } if (nearlyEqual(fn, SkNamedTransferFn::k2Dot2) && nearlyEqual(gamut, SkNamedGamut::kAdobeRGB)) { return ADATASPACE_ADOBE_RGB; } if (nearlyEqual(fn, SkNamedTransferFn::kRec2020) && nearlyEqual(gamut, SkNamedGamut::kRec2020)) { return ADATASPACE_BT2020; } if (nearlyEqual(fn, k2Dot6) && nearlyEqual(gamut, kDCIP3)) { return ADATASPACE_DCI_P3; } return ADATASPACE_UNKNOWN; return (ADataSpace)uirenderer::ColorSpaceToADataSpace(info.colorSpace(), info.colorType()); } AndroidBitmapInfo ABitmap_getInfoFromJava(JNIEnv* env, jobject bitmapObj) { Loading
libs/hwui/utils/Color.cpp +86 −3 Original line number Diff line number Diff line Loading @@ -108,7 +108,9 @@ SkColorType PixelFormatToColorType(android::PixelFormat format) { } } // FIXME: Share with the version in android_bitmap.cpp? namespace { static constexpr skcms_TransferFunction k2Dot6 = {2.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}; // Skia's SkNamedGamut::kDCIP3 is based on a white point of D65. This gamut // matches the white point used by ColorSpace.Named.DCIP3. static constexpr skcms_Matrix3x3 kDCIP3 = {{ Loading @@ -117,6 +119,87 @@ static constexpr skcms_Matrix3x3 kDCIP3 = {{ {0.000800549, 0.0432385, 0.78275}, }}; static bool nearlyEqual(float a, float b) { // By trial and error, this is close enough to match for the ADataSpaces we // compare for. return ::fabs(a - b) < .002f; } static bool nearlyEqual(const skcms_TransferFunction& x, const skcms_TransferFunction& y) { return nearlyEqual(x.g, y.g) && nearlyEqual(x.a, y.a) && nearlyEqual(x.b, y.b) && nearlyEqual(x.c, y.c) && nearlyEqual(x.d, y.d) && nearlyEqual(x.e, y.e) && nearlyEqual(x.f, y.f); } static bool nearlyEqual(const skcms_Matrix3x3& x, const skcms_Matrix3x3& y) { for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (!nearlyEqual(x.vals[i][j], y.vals[i][j])) return false; } } return true; } } // anonymous namespace android_dataspace ColorSpaceToADataSpace(SkColorSpace* colorSpace, SkColorType colorType) { if (!colorSpace) { return HAL_DATASPACE_UNKNOWN; } if (colorSpace->isSRGB()) { if (colorType == kRGBA_F16_SkColorType) { return HAL_DATASPACE_V0_SCRGB; } return HAL_DATASPACE_V0_SRGB; } skcms_TransferFunction fn; LOG_ALWAYS_FATAL_IF(!colorSpace->isNumericalTransferFn(&fn)); skcms_Matrix3x3 gamut; LOG_ALWAYS_FATAL_IF(!colorSpace->toXYZD50(&gamut)); if (nearlyEqual(gamut, SkNamedGamut::kSRGB)) { if (nearlyEqual(fn, SkNamedTransferFn::kLinear)) { // Skia doesn't differentiate amongst the RANGES. In Java, we associate // LINEAR_EXTENDED_SRGB with F16, and LINEAR_SRGB with other Configs. // Make the same association here. if (colorType == kRGBA_F16_SkColorType) { return HAL_DATASPACE_V0_SCRGB_LINEAR; } return HAL_DATASPACE_V0_SRGB_LINEAR; } if (nearlyEqual(fn, SkNamedTransferFn::kRec2020)) { return HAL_DATASPACE_V0_BT709; } } if (nearlyEqual(fn, SkNamedTransferFn::kSRGB) && nearlyEqual(gamut, SkNamedGamut::kDCIP3)) { return HAL_DATASPACE_DISPLAY_P3; } if (nearlyEqual(fn, SkNamedTransferFn::k2Dot2) && nearlyEqual(gamut, SkNamedGamut::kAdobeRGB)) { return HAL_DATASPACE_ADOBE_RGB; } if (nearlyEqual(fn, SkNamedTransferFn::kRec2020) && nearlyEqual(gamut, SkNamedGamut::kRec2020)) { return HAL_DATASPACE_BT2020; } if (nearlyEqual(fn, k2Dot6) && nearlyEqual(gamut, kDCIP3)) { return HAL_DATASPACE_DCI_P3; } return HAL_DATASPACE_UNKNOWN; } sk_sp<SkColorSpace> DataSpaceToColorSpace(android_dataspace dataspace) { if (dataspace == HAL_DATASPACE_UNKNOWN) { return SkColorSpace::MakeSRGB(); Loading @@ -126,7 +209,7 @@ sk_sp<SkColorSpace> DataSpaceToColorSpace(android_dataspace dataspace) { // needs to use the locally-defined kDCIP3 gamut, rather than the one in // Skia (SkNamedGamut), which is used for other data spaces with // HAL_DATASPACE_STANDARD_DCI_P3 (e.g. HAL_DATASPACE_DISPLAY_P3). return SkColorSpace::MakeRGB({2.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, kDCIP3); return SkColorSpace::MakeRGB(k2Dot6, kDCIP3); } skcms_Matrix3x3 gamut; Loading Loading @@ -165,7 +248,7 @@ sk_sp<SkColorSpace> DataSpaceToColorSpace(android_dataspace dataspace) { case HAL_DATASPACE_TRANSFER_GAMMA2_2: return SkColorSpace::MakeRGB({2.2f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, gamut); case HAL_DATASPACE_TRANSFER_GAMMA2_6: return SkColorSpace::MakeRGB({2.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, gamut); return SkColorSpace::MakeRGB(k2Dot6, gamut); case HAL_DATASPACE_TRANSFER_GAMMA2_8: return SkColorSpace::MakeRGB({2.8f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, gamut); case HAL_DATASPACE_TRANSFER_ST2084: Loading
libs/hwui/utils/Color.h +16 −0 Original line number Diff line number Diff line Loading @@ -105,6 +105,22 @@ ANDROID_API SkColorType PixelFormatToColorType(android::PixelFormat format); ANDROID_API sk_sp<SkColorSpace> DataSpaceToColorSpace(android_dataspace dataspace); /** * Return the android_dataspace corresponding to colorSpace. * * Note: This currently only returns android_dataspaces with corresponding * ADataSpaces. The NDK relies on this, so if you need to update it to return * an android_dataspace *without* an ADataSpace, the NDK methods need to be * updated. * * @param colorSpace May be null, in which case this will return * HAL_DATASPACE_UNKNOWN. * @param colorType Some SkColorSpaces are associated with more than one * android_dataspace. In that case, the SkColorType is used to * determine which one to return. */ ANDROID_API android_dataspace ColorSpaceToADataSpace(SkColorSpace*, SkColorType); struct Lab { float L; float a; Loading