aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar brianosman <brianosman@google.com>2016-04-19 09:18:11 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-04-19 09:18:11 -0700
commit3c579dcff81dab48a5fb3801d7a34f9c00256ec4 (patch)
tree455f7706c04b0b1c73d767efd41483fa6a0f721f
parent7e6695416e20a741dae6db5940aa44a3e099a62d (diff)
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
-rw-r--r--dm/DM.cpp72
-rw-r--r--gyp/dm.gypi1
-rw-r--r--gyp/tools.gyp3
-rw-r--r--tools/picture_utils.cpp74
-rw-r--r--tools/picture_utils.h10
5 files changed, 94 insertions, 66 deletions
diff --git a/dm/DM.cpp b/dm/DM.cpp
index ecf231ed63..58cb773e03 100644
--- a/dm/DM.cpp
+++ b/dm/DM.cpp
@@ -17,6 +17,7 @@
#include "SkColorPriv.h"
#include "SkCommonFlags.h"
#include "SkCommonFlagsConfig.h"
+#include "SkData.h"
#include "SkFontMgr.h"
#include "SkGraphics.h"
#include "SkHalf.h"
@@ -30,6 +31,7 @@
#include "SkThreadUtils.h"
#include "Test.h"
#include "Timer.h"
+#include "picture_utils.h"
#include "sk_tool_utils.h"
#ifdef SK_PDF_IMAGE_STATS
@@ -924,72 +926,12 @@ 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.
-
- 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;
- }
- 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 false;
- }
- 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 {
- // 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;
- }
+ sk_sp<SkData> encodedBitmap = sk_tools::encode_bitmap_for_png(bitmap);
+ if (encodedBitmap.get() == nullptr) {
+ return false;
}
+ uint32_t* rgba = static_cast<uint32_t*>(encodedBitmap.get()->writable_data());
// We don't need bitmap anymore. Might as well drop our ref.
bitmap.reset();
@@ -1036,7 +978,7 @@ static bool dump_png(SkBitmap bitmap, const char* path, const char* md5) {
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
png_write_info(png, info);
for (int j = 0; j < h; j++) {
- png_bytep row = (png_bytep)(rgba.get() + w*j);
+ png_bytep row = (png_bytep)(rgba + w*j);
png_write_rows(png, &row, 1);
}
png_write_end(png, info);
diff --git a/gyp/dm.gypi b/gyp/dm.gypi
index 337bcccd7c..b14c87e5c6 100644
--- a/gyp/dm.gypi
+++ b/gyp/dm.gypi
@@ -24,6 +24,7 @@
'skia_lib.gyp:skia_lib',
'svg.gyp:svg',
'tools.gyp:crash_handler',
+ 'tools.gyp:picture_utils',
'tools.gyp:proc_stats',
'tools.gyp:sk_tool_utils',
'tools.gyp:url_data_manager',
diff --git a/gyp/tools.gyp b/gyp/tools.gyp
index 190e1fe5a8..8af0dfd1ac 100644
--- a/gyp/tools.gyp
+++ b/gyp/tools.gyp
@@ -351,6 +351,9 @@
'../tools/picture_utils.cpp',
'../tools/picture_utils.h',
],
+ 'include_dirs': [
+ '../src/core/',
+ ],
'dependencies': [
'skia_lib.gyp:skia_lib',
],
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<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);
+
+ 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<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 {
+ // 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
diff --git a/tools/picture_utils.h b/tools/picture_utils.h
index 1373020a5b..49a2c821a4 100644
--- a/tools/picture_utils.h
+++ b/tools/picture_utils.h
@@ -8,7 +8,9 @@
#ifndef picture_utils_DEFINED
#define picture_utils_DEFINED
-class SkBitmap;
+#include "SkBitmap.h"
+
+class SkData;
class SkString;
namespace sk_tools {
@@ -47,6 +49,12 @@ namespace sk_tools {
bool write_bitmap_to_disk(const SkBitmap& bm, const SkString& dirPath,
const char *subdirOrNull, const SkString& baseName);
+ // Return raw unpremultiplied RGBA bytes, suitable for storing in a PNG. The output
+ // colors are assumed to be sRGB values. This is only guaranteed to work for the
+ // cases that are currently emitted by tools:
+ // Linear premul 8888, sRGB premul 8888, Linear premul F16
+ sk_sp<SkData> encode_bitmap_for_png(SkBitmap bitmap);
+
} // namespace sk_tools
#endif // picture_utils_DEFINED