Index: dm/DM.cpp |
diff --git a/dm/DM.cpp b/dm/DM.cpp |
index 9021f3c7894097631cef8ac3a5303a5178dc6a70..59c7def4d67d0dbee83fd9d3db10686f5a490a6b 100644 |
--- a/dm/DM.cpp |
+++ b/dm/DM.cpp |
@@ -14,13 +14,16 @@ |
#include "SkBBHFactory.h" |
#include "SkChecksum.h" |
#include "SkCodec.h" |
+#include "SkColorPriv.h" |
#include "SkCommonFlags.h" |
#include "SkCommonFlagsConfig.h" |
#include "SkFontMgr.h" |
#include "SkGraphics.h" |
+#include "SkHalf.h" |
#include "SkMD5.h" |
#include "SkMutex.h" |
#include "SkOSFile.h" |
+#include "SkPM4fPriv.h" |
#include "SkSpinlock.h" |
#include "SkTHash.h" |
#include "SkTaskGroup.h" |
@@ -700,6 +703,8 @@ static Sink* create_sink(const SkCommandLineConfig* config) { |
if (FLAGS_cpu) { |
SINK("565", RasterSink, kRGB_565_SkColorType); |
SINK("8888", RasterSink, kN32_SkColorType); |
+ SINK("srgb", RasterSink, kN32_SkColorType, kSRGB_SkColorProfileType); |
+ SINK("f16", RasterSink, kRGBA_F16_SkColorType); |
SINK("pdf", PDFSink, "Pdfium"); |
SINK("pdf_poppler", PDFSink, "Poppler"); |
SINK("skp", SKPSink); |
@@ -777,21 +782,66 @@ static void gather_sinks() { |
static bool dump_png(SkBitmap bitmap, const char* path, const char* md5) { |
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. |
- // First get the bitmap into N32 color format. The next step will work only there. |
- if (bitmap.colorType() != kN32_SkColorType) { |
- SkBitmap n32; |
- if (!bitmap.copyTo(&n32, kN32_SkColorType)) { |
+ SkAutoTMalloc<uint32_t> 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 false; |
} |
- bitmap = n32; |
- } |
+ 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. |
+ } |
- // Convert our N32 bitmap into unpremul RGBA for libpng. |
- SkAutoTMalloc<uint32_t> rgba(w*h); |
- if (!bitmap.readPixels(SkImageInfo::Make(w,h, kRGBA_8888_SkColorType, kUnpremul_SkAlphaType), |
- rgba, 4*w, 0,0)) { |
- return false; |
+ } 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 false; |
+ } |
+ for (int i = 0; i < w*h; i++) { |
+ Sk4f fs = SkHalfToFloat_01(px[i]); // Convert up to linear floats. |
+ 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 false; |
+ } |
+ 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 false; |
+ } |
} |
// We don't need bitmap anymore. Might as well drop our ref. |