From b0bd1516bff3f5afcbfd615e805867531657811b Mon Sep 17 00:00:00 2001 From: halcanary Date: Tue, 8 Dec 2015 10:29:58 -0800 Subject: [PATCH] default SkPixelSerializer Add SkImageEncoder::EncodeData(const SkPixmap&, ...) function. Add SkImageEncoder::CreatePixelSerializer() to return a PixelSerializer that calls into SkImageEncoder::EncodeData. SkImage::encode() make use of SkImageEncoder::CreatePixelSerializer. Review URL: https://codereview.chromium.org/1507123002 --- debugger/QT/SkDebuggerGUI.cpp | 5 +++-- include/core/SkImageEncoder.h | 8 ++++++++ src/image/SkImage.cpp | 33 ++++++++------------------------- src/images/SkImageEncoder.cpp | 33 +++++++++++++++++++++++++++++++-- tests/PictureTest.cpp | 5 +++-- tools/sk_tool_utils.h | 12 ------------ 6 files changed, 53 insertions(+), 43 deletions(-) diff --git a/debugger/QT/SkDebuggerGUI.cpp b/debugger/QT/SkDebuggerGUI.cpp index 4422334496..0d009b3ffa 100644 --- a/debugger/QT/SkDebuggerGUI.cpp +++ b/debugger/QT/SkDebuggerGUI.cpp @@ -281,8 +281,9 @@ void SkDebuggerGUI::saveToFile(const SkString& filename) { SkFILEWStream file(filename.c_str()); SkAutoTUnref copy(fDebugger.copyPicture()); - sk_tool_utils::PngPixelSerializer serializer; - copy->serialize(&file, &serializer); + SkAutoTUnref serializer( + SkImageEncoder::CreatePixelSerializer()); + copy->serialize(&file, serializer); } void SkDebuggerGUI::loadFile(QListWidgetItem *item) { diff --git a/include/core/SkImageEncoder.h b/include/core/SkImageEncoder.h index fc999dcc18..bb3341f836 100644 --- a/include/core/SkImageEncoder.h +++ b/include/core/SkImageEncoder.h @@ -12,6 +12,8 @@ #include "SkTRegistry.h" class SkBitmap; +class SkPixelSerializer; +class SkPixmap; class SkData; class SkWStream; @@ -64,11 +66,17 @@ public: Type, int quality); static SkData* EncodeData(const SkBitmap&, Type, int quality); + static SkData* EncodeData(const SkPixmap&, Type, int quality); + static bool EncodeFile(const char file[], const SkBitmap&, Type, int quality); static bool EncodeStream(SkWStream*, const SkBitmap&, Type, int quality); + /** Uses SkImageEncoder to serialize images that are not already + encoded as SkImageEncoder::kPNG_Type images. */ + static SkPixelSerializer* CreatePixelSerializer(); + protected: /** * Encode bitmap 'bm' in the desired format, writing results to diff --git a/src/image/SkImage.cpp b/src/image/SkImage.cpp index 7db5b4e0a8..338ab09130 100644 --- a/src/image/SkImage.cpp +++ b/src/image/SkImage.cpp @@ -9,6 +9,7 @@ #include "SkBitmapCache.h" #include "SkCanvas.h" #include "SkData.h" +#include "SkImageEncoder.h" #include "SkImageGenerator.h" #include "SkImagePriv.h" #include "SkImageShader.h" @@ -178,32 +179,14 @@ SkData* SkImage::encode(SkImageEncoder::Type type, int quality) const { return nullptr; } -namespace { - -class DefaultSerializer : public SkPixelSerializer { -protected: - bool onUseEncodedData(const void *data, size_t len) override { - return true; - } - SkData* onEncode(const SkPixmap& pixmap) override { - SkBitmap bm; - if (!bm.installPixels(pixmap.info(), - const_cast(pixmap.addr()), - pixmap.rowBytes(), - pixmap.ctable(), - nullptr, nullptr)) { - return nullptr; - } - return SkImageEncoder::EncodeData(bm, SkImageEncoder::kPNG_Type, 100); - } -}; - -} // anonymous namespace - SkData* SkImage::encode(SkPixelSerializer* serializer) const { - DefaultSerializer defaultSerializer; - SkPixelSerializer* effectiveSerializer = serializer ? serializer : &defaultSerializer; - + SkAutoTUnref defaultSerializer; + SkPixelSerializer* effectiveSerializer = serializer; + if (!effectiveSerializer) { + defaultSerializer.reset(SkImageEncoder::CreatePixelSerializer()); + SkASSERT(defaultSerializer.get()); + effectiveSerializer = defaultSerializer.get(); + } SkAutoTUnref encoded(this->refEncoded()); if (encoded && effectiveSerializer->useEncodedData(encoded->data(), encoded->size())) { return encoded.detach(); diff --git a/src/images/SkImageEncoder.cpp b/src/images/SkImageEncoder.cpp index cc1b73baa5..cea567816b 100644 --- a/src/images/SkImageEncoder.cpp +++ b/src/images/SkImageEncoder.cpp @@ -7,6 +7,8 @@ #include "SkImageEncoder.h" #include "SkBitmap.h" +#include "SkPixelSerializer.h" +#include "SkPixmap.h" #include "SkStream.h" #include "SkTemplates.h" @@ -57,6 +59,33 @@ SkData* SkImageEncoder::EncodeData(const SkImageInfo& info, const void* pixels, if (!bm.installPixels(info, const_cast(pixels), rowBytes)) { return nullptr; } - SkAutoTDelete enc(SkImageEncoder::Create(t)); - return enc.get() ? enc.get()->encodeData(bm, quality) : nullptr; + bm.setImmutable(); + return SkImageEncoder::EncodeData(bm, t, quality); +} + +SkData* SkImageEncoder::EncodeData(const SkPixmap& pixmap, + Type t, int quality) { + SkBitmap bm; + if (!bm.installPixels(pixmap.info(), + const_cast(pixmap.addr()), + pixmap.rowBytes(), + pixmap.ctable(), nullptr, nullptr)) { + return nullptr; + } + bm.setImmutable(); + return SkImageEncoder::EncodeData(bm, t, quality); +} + +namespace { +class ImageEncoderPixelSerializer final : public SkPixelSerializer { +protected: + bool onUseEncodedData(const void*, size_t) override { return true; } + SkData* onEncode(const SkPixmap& pmap) override { + return SkImageEncoder::EncodeData(pmap, SkImageEncoder::kPNG_Type, 100); + } +}; +} // namespace + +SkPixelSerializer* SkImageEncoder::CreatePixelSerializer() { + return new ImageEncoderPixelSerializer; } diff --git a/tests/PictureTest.cpp b/tests/PictureTest.cpp index 1575456491..a81733e38a 100644 --- a/tests/PictureTest.cpp +++ b/tests/PictureTest.cpp @@ -851,8 +851,9 @@ static SkData* serialized_picture_from_bitmap(const SkBitmap& bitmap) { SkAutoTUnref picture(recorder.endRecording()); SkDynamicMemoryWStream wStream; - sk_tool_utils::PngPixelSerializer serializer; - picture->serialize(&wStream, &serializer); + SkAutoTUnref serializer( + SkImageEncoder::CreatePixelSerializer()); + picture->serialize(&wStream, serializer); return wStream.copyToData(); } diff --git a/tools/sk_tool_utils.h b/tools/sk_tool_utils.h index 67fd869a87..dab42e31fd 100644 --- a/tools/sk_tool_utils.h +++ b/tools/sk_tool_utils.h @@ -114,18 +114,6 @@ namespace sk_tool_utils { SkBitmap create_string_bitmap(int w, int h, SkColor c, int x, int y, int textSize, const char* str); - // Encodes to PNG, unless there is already encoded data, in which case that gets - // used. - class PngPixelSerializer : public SkPixelSerializer { - public: - bool onUseEncodedData(const void*, size_t) override { return true; } - SkData* onEncodePixels(const SkImageInfo& info, const void* pixels, - size_t rowBytes) override { - return SkImageEncoder::EncodeData(info, pixels, rowBytes, - SkImageEncoder::kPNG_Type, 100); - } - }; - // A helper for inserting a drawtext call into a SkTextBlobBuilder void add_to_text_blob(SkTextBlobBuilder* builder, const char* text, const SkPaint& origPaint, SkScalar x, SkScalar y);