void draw(SkCanvas* canvas) { SkBitmap bitmap; bitmap.setInfo(SkImageInfo::MakeN32(16, 32, kPremul_SkAlphaType, SkColorSpace::MakeSRGBLinear())); SkColorSpace* colorSpace = bitmap.colorSpace(); SkDebugf("gammaCloseToSRGB: %s gammaIsLinear: %s isSRGB: %s\n", colorSpace->gammaCloseToSRGB() ? "true" : "false", colorSpace->gammaIsLinear() ? "true" : "false", colorSpace->isSRGB() ? "true" : "false"); }
sk_sp<SkData> encode_bitmap_for_png(SkBitmap bitmap) { const int w = bitmap.width(), h = bitmap.height(); // PNG wants unpremultiplied 8-bit RGBA pixels (16-bit could work fine too). // We leave the gamma of these bytes unspecified, to continue the status quo, // which we think generally is to interpret them as sRGB. SkAutoTMalloc<uint32_t> rgba(w*h); auto srgbColorSpace = SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named); if (bitmap. colorType() == kN32_SkColorType && bitmap.colorSpace() == srgbColorSpace.get()) { // These are premul sRGB 8-bit pixels in SkPMColor order. // We want unpremul sRGB 8-bit pixels in RGBA order. We'll get there via floats. bitmap.lockPixels(); auto px = (const uint32_t*)bitmap.getPixels(); if (!px) { return nullptr; } for (int i = 0; i < w*h; i++) { Sk4f fs = Sk4f_fromS32(px[i]); // Convert up to linear floats. #if defined(SK_PMCOLOR_IS_BGRA) fs = SkNx_shuffle<2,1,0,3>(fs); // Shuffle to RGBA, if not there already. #endif float invA = 1.0f / fs[3]; fs = fs * Sk4f(invA, invA, invA, 1); // Unpremultiply. rgba[i] = Sk4f_toS32(fs); // Pack down to sRGB bytes. } } else if (bitmap.colorType() == kRGBA_F16_SkColorType) { // These are premul linear half-float pixels in RGBA order. // We want unpremul sRGB 8-bit pixels in RGBA order. We'll get there via floats. bitmap.lockPixels(); auto px = (const uint64_t*)bitmap.getPixels(); if (!px) { return nullptr; } for (int i = 0; i < w*h; i++) { // Convert up to linear floats. Sk4f fs(SkHalfToFloat(static_cast<SkHalf>(px[i] >> (0 * 16))), SkHalfToFloat(static_cast<SkHalf>(px[i] >> (1 * 16))), SkHalfToFloat(static_cast<SkHalf>(px[i] >> (2 * 16))), SkHalfToFloat(static_cast<SkHalf>(px[i] >> (3 * 16)))); fs = Sk4f::Max(0.0f, Sk4f::Min(fs, 1.0f)); // Clamp float invA = 1.0f / fs[3]; fs = fs * Sk4f(invA, invA, invA, 1); // Unpremultiply. rgba[i] = Sk4f_toS32(fs); // Pack down to sRGB bytes. } } else {