aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools/picture_utils.cpp
diff options
context:
space:
mode:
authorGravatar Mike Klein <mtklein@chromium.org>2017-06-12 08:59:16 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-06-12 14:41:15 +0000
commitfc3341632fc04264e968bd1996ccb73b95088084 (patch)
tree7e3dd151c7d488b6b9377b1425500c51b6ffbbf5 /tools/picture_utils.cpp
parent197ca9b0d14fafecd0d9fda1711b327036384415 (diff)
port encode_bitmap_for_png() to SkRasterPipeline
This logically shouldn't change anything, but it does a bit: - no diffs in 565 - sRGB and 8888 show minor diffs, only when unpremul is non-trivial - f16 shows minor diffs all over, and major ones in shallow gradients I think the shallow gradient diffs make sense. F16's high-precision is being quantized down to a much narrower range (something like 10-40 values), so where the lines are drawn between sRGB bits will come down to all sorts of things, especially rounding. Change-Id: I156b7c613b73d6d6089221e61d0c529798ac1f9f Reviewed-on: https://skia-review.googlesource.com/19449 Reviewed-by: Brian Osman <brianosman@google.com> Commit-Queue: Mike Klein <mtklein@chromium.org>
Diffstat (limited to 'tools/picture_utils.cpp')
-rw-r--r--tools/picture_utils.cpp89
1 files changed, 32 insertions, 57 deletions
diff --git a/tools/picture_utils.cpp b/tools/picture_utils.cpp
index db245538d4..5e87639ffc 100644
--- a/tools/picture_utils.cpp
+++ b/tools/picture_utils.cpp
@@ -16,6 +16,7 @@
#include "SkPicture.h"
#include "SkStream.h"
#include "SkString.h"
+#include "SkRasterPipeline.h"
#include "sk_tool_utils.h"
@@ -74,71 +75,45 @@ namespace sk_tools {
sk_sp<SkData> encode_bitmap_for_png(SkBitmap bitmap) {
const int w = bitmap.width(),
- h = bitmap.height();
+ 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::MakeSRGB();
- 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.
- 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.
- }
+ const void* src = bitmap.getPixels();
+ uint32_t* dst = rgba.get();
- } 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.
- 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))));
- if (fs[3]) { // Unpremultiply.
- fs *= Sk4f(1/fs[3], 1/fs[3], 1/fs[3], 1);
- }
- fs = Sk4f::Max(0.0f, Sk4f::Min(fs, 1.0f)); // Clamp to [0,1].
- 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 (!sk_tool_utils::copy_to(&n32, kN32_SkColorType, bitmap)) {
- return nullptr;
- }
- bitmap = n32;
- }
+ SkRasterPipeline_<256> p;
+ switch (bitmap.colorType()) {
+ case kRGBA_F16_SkColorType: p.append(SkRasterPipeline::load_f16, &src); break;
+ case kRGBA_8888_SkColorType:
+ case kBGRA_8888_SkColorType: p.append(SkRasterPipeline::load_8888, &src); break;
+ case kRGB_565_SkColorType: p.append(SkRasterPipeline::load_565, &src); break;
+ default: SkASSERT(false); // DM doesn't support any other formats, does it?
+ }
+ if (bitmap.info().gammaCloseToSRGB()) {
+ p.append(SkRasterPipeline::from_srgb);
+ }
+ if (bitmap.colorType() == kBGRA_8888_SkColorType) {
+ p.append(SkRasterPipeline::swap_rb);
+ }
+ p.append(SkRasterPipeline::unpremul);
+ p.append(SkRasterPipeline::clamp_0);
+ p.append(SkRasterPipeline::clamp_1);
+ if (bitmap.info().colorSpace()) {
+ // We leave legacy modes as-is. They're already sRGB encoded (kind of).
+ p.append(SkRasterPipeline::to_srgb);
+ }
+ p.append(SkRasterPipeline::store_8888, &dst);
- // 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;
- }
+ auto run = p.compile();
+ for (int y = 0; y < h; y++) {
+ run(0,y, w);
+ src = SkTAddOffset<const void>(src, bitmap.rowBytes());
+ dst += w;
}
return SkData::MakeFromMalloc(rgba.release(), w*h*sizeof(uint32_t));