From 3c579dcff81dab48a5fb3801d7a34f9c00256ec4 Mon Sep 17 00:00:00 2001 From: brianosman Date: Tue, 19 Apr 2016 09:18:11 -0700 Subject: Move DM png code to picture_utils, for use by other tools. Planning to re-use this code in skiaserve in an upcoming change. TBR=mtklein@google.com BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1901113002 Review URL: https://codereview.chromium.org/1901113002 --- tools/picture_utils.cpp | 74 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) (limited to 'tools/picture_utils.cpp') diff --git a/tools/picture_utils.cpp b/tools/picture_utils.cpp index 9661daf2d0..63a48ce3e1 100644 --- a/tools/picture_utils.cpp +++ b/tools/picture_utils.cpp @@ -8,8 +8,10 @@ #include "picture_utils.h" #include "SkBitmap.h" #include "SkColorPriv.h" +#include "SkHalf.h" #include "SkImageEncoder.h" #include "SkOSFile.h" +#include "SkPM4fPriv.h" #include "SkPicture.h" #include "SkStream.h" #include "SkString.h" @@ -69,4 +71,76 @@ namespace sk_tools { } } + sk_sp 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 rgba(w*h); + + if (bitmap. colorType() == kN32_SkColorType && + bitmap.profileType() == kSRGB_SkColorProfileType) { + // 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(px[i] >> (0 * 16))), + SkHalfToFloat(static_cast(px[i] >> (1 * 16))), + SkHalfToFloat(static_cast(px[i] >> (2 * 16))), + SkHalfToFloat(static_cast(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 { + // We "should" gamma correct in here but we don't. + // We want Gold to show exactly what our clients are seeing, broken gamma. + + // Convert smaller formats up to premul linear 8-bit (in SkPMColor order). + if (bitmap.colorType() != kN32_SkColorType) { + SkBitmap n32; + if (!bitmap.copyTo(&n32, kN32_SkColorType)) { + return nullptr; + } + bitmap = n32; + } + + // Convert premul linear 8-bit to unpremul linear 8-bit RGBA. + if (!bitmap.readPixels(SkImageInfo::Make(w,h, kRGBA_8888_SkColorType, + kUnpremul_SkAlphaType), + rgba, 4*w, 0,0)) { + return nullptr; + } + } + + return SkData::MakeFromMalloc(rgba.release(), w*h*sizeof(uint32_t)); + } + } // namespace sk_tools -- cgit v1.2.3