diff options
author | Hal Canary <halcanary@google.com> | 2016-11-23 08:55:18 -0700 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2016-11-23 16:40:32 +0000 |
commit | db6830162eca5b94e61d9825ec93306fc615d204 (patch) | |
tree | 02be1aa930879c2b389e80beb4910c8d27027257 | |
parent | 45580d3e3024c1536e8e1b2017b704805442b634 (diff) |
SkImageEncoder: simplify API
(re-land 248ff02 & 2cb6cb7, with changes)
- Hide SkImageEncoder class in private header.
- SkImageEncoder::Type becomes SkEncodedImageFormat
- SkEncodedFormat becomes SkEncodedImageFormat
- SkImageEncoder static functions replaced with
single function EncodeImage()
- utility wrappers for EncodeImage() are in
sk_tool_utils.h
TODO: remove link-time registration mechanism.
TODO: clean up clients use of API and flip the flag.
TODO: implement EncodeImage() in chromeium/skia/ext
Change-Id: I47d451e50be4d5c6c130869c7fa7c2857243d9f0
Reviewed-on: https://skia-review.googlesource.com/4909
Reviewed-by: Mike Reed <reed@google.com>
Reviewed-by: Leon Scroggins <scroggo@google.com>
Reviewed-on: https://skia-review.googlesource.com/5186
Commit-Queue: Hal Canary <halcanary@google.com>
Reviewed-by: Hal Canary <halcanary@google.com>
67 files changed, 478 insertions, 409 deletions
@@ -1243,6 +1243,7 @@ if (skia_enable_tools) { deps = [ ":flags", ":skia", + ":tool_utils", ] testonly = true } diff --git a/bench/EncoderBench.cpp b/bench/EncoderBench.cpp index d7ddfbc602..f0adaa1071 100644 --- a/bench/EncoderBench.cpp +++ b/bench/EncoderBench.cpp @@ -11,9 +11,11 @@ #include "SkData.h" #include "SkImageEncoder.h" +#include "sk_tool_utils.h" + class EncodeBench : public Benchmark { public: - EncodeBench(const char* filename, SkImageEncoder::Type type, int quality) + EncodeBench(const char* filename, SkEncodedImageFormat type, int quality) : fFilename(filename) , fType(type) , fQuality(quality) @@ -23,13 +25,13 @@ public: name.append(filename); name.append("_"); switch (type) { - case SkImageEncoder::kJPEG_Type: + case SkEncodedImageFormat::kJPEG: name.append("JPEG"); break; - case SkImageEncoder::kPNG_Type: + case SkEncodedImageFormat::kPNG: name.append("PNG"); break; - case SkImageEncoder::kWEBP_Type: + case SkEncodedImageFormat::kWEBP: name.append("WEBP"); break; default: @@ -54,14 +56,14 @@ public: void onDraw(int loops, SkCanvas*) override { for (int i = 0; i < loops; i++) { - sk_sp<SkData> data(SkImageEncoder::EncodeData(fBitmap, fType, fQuality)); + sk_sp<SkData> data(sk_tool_utils::EncodeImageToData(fBitmap, fType, fQuality)); SkASSERT(data); } } private: const char* fFilename; - const SkImageEncoder::Type fType; + const SkEncodedImageFormat fType; const int fQuality; SkString fName; SkBitmap fBitmap; @@ -69,13 +71,13 @@ private: // The Android Photos app uses a quality of 90 on JPEG encodes -DEF_BENCH(return new EncodeBench("mandrill_512.png", SkImageEncoder::kJPEG_Type, 90)); -DEF_BENCH(return new EncodeBench("color_wheel.jpg", SkImageEncoder::kJPEG_Type, 90)); +DEF_BENCH(return new EncodeBench("mandrill_512.png", SkEncodedImageFormat::kJPEG, 90)); +DEF_BENCH(return new EncodeBench("color_wheel.jpg", SkEncodedImageFormat::kJPEG, 90)); // PNG encodes are lossless so quality should be ignored -DEF_BENCH(return new EncodeBench("mandrill_512.png", SkImageEncoder::kPNG_Type, 90)); -DEF_BENCH(return new EncodeBench("color_wheel.jpg", SkImageEncoder::kPNG_Type, 90)); +DEF_BENCH(return new EncodeBench("mandrill_512.png", SkEncodedImageFormat::kPNG, 90)); +DEF_BENCH(return new EncodeBench("color_wheel.jpg", SkEncodedImageFormat::kPNG, 90)); // TODO: What is the appropriate quality to use to benchmark WEBP encodes? -DEF_BENCH(return new EncodeBench("mandrill_512.png", SkImageEncoder::kWEBP_Type, 90)); -DEF_BENCH(return new EncodeBench("color_wheel.jpg", SkImageEncoder::kWEBP_Type, 90)); +DEF_BENCH(return new EncodeBench("mandrill_512.png", SkEncodedImageFormat::kWEBP, 90)); +DEF_BENCH(return new EncodeBench("color_wheel.jpg", SkEncodedImageFormat::kWEBP, 90)); diff --git a/bench/GLBench.cpp b/bench/GLBench.cpp index a39edeee7f..cb824daadc 100644 --- a/bench/GLBench.cpp +++ b/bench/GLBench.cpp @@ -15,6 +15,8 @@ #include "SkSLCompiler.h" #include <stdio.h> +#include "sk_tool_utils.h" + const GrGLContext* GLBench::getGLContext(SkCanvas* canvas) { // This bench exclusively tests GL calls directly if (nullptr == canvas->getGrContext()) { @@ -181,7 +183,7 @@ void GLBench::DumpImage(const GrGLInterface* gl, uint32_t screenWidth, uint32_t bm.setPixels(readback.get()); - if (!SkImageEncoder::EncodeFile(filename, bm, SkImageEncoder::kPNG_Type, 100)) { + if (!sk_tool_utils::EncodeImageToFile(filename, bm, SkEncodedImageFormat::kPNG, 100)) { SkDebugf("------ failed to encode %s\n", filename); remove(filename); // remove any partial file return; diff --git a/bench/nanobench.cpp b/bench/nanobench.cpp index 9b4db96d01..35872427af 100644 --- a/bench/nanobench.cpp +++ b/bench/nanobench.cpp @@ -300,7 +300,7 @@ static bool write_canvas_png(Target* target, const SkString& filename) { SkDebugf("Can't write %s.\n", filename.c_str()); return false; } - if (!SkImageEncoder::EncodeStream(&stream, bmp, SkImageEncoder::kPNG_Type, 100)) { + if (!SkEncodeImage(&stream, bmp, SkEncodedImageFormat::kPNG, 100)) { SkDebugf("Can't encode a PNG.\n"); return false; } diff --git a/cmake/example.cpp b/cmake/example.cpp index 38ce901450..ca6e55eb68 100644 --- a/cmake/example.cpp +++ b/cmake/example.cpp @@ -82,7 +82,7 @@ int main(int, char**) { // Grab a snapshot of the surface as an immutable SkImage. sk_sp<SkImage> image = surface->makeImageSnapshot(); // Encode that image as a .png into a blob in memory. - std::shared_ptr<SkData> png = adopt(image->encode(SkImageEncoder::kPNG_Type, 100)); + std::shared_ptr<SkData> png = adopt(image->encode(SkEncodedImageFormat::kPNG, 100)); // This code is no longer Skia-specific. We just dump the .png to disk. Any way works. static const char* path = "example.png"; diff --git a/debugger/QT/SkDebuggerGUI.cpp b/debugger/QT/SkDebuggerGUI.cpp index 1437faf02a..601318334a 100644 --- a/debugger/QT/SkDebuggerGUI.cpp +++ b/debugger/QT/SkDebuggerGUI.cpp @@ -281,8 +281,7 @@ void SkDebuggerGUI::saveToFile(const SkString& filename) { SkFILEWStream file(filename.c_str()); sk_sp<SkPicture> copy(fDebugger.copyPicture()); - sk_sp<SkPixelSerializer> serializer( - SkImageEncoder::CreatePixelSerializer()); + sk_sp<SkPixelSerializer> serializer(sk_tool_utils::MakePixelSerializer()); copy->serialize(&file, serializer.get()); } @@ -524,17 +524,17 @@ static void push_codec_srcs(Path path) { nativeModes.push_back(CodecSrc::kCodec_Mode); nativeModes.push_back(CodecSrc::kCodecZeroInit_Mode); switch (codec->getEncodedFormat()) { - case SkEncodedFormat::kJPEG_SkEncodedFormat: + case SkEncodedImageFormat::kJPEG: nativeModes.push_back(CodecSrc::kScanline_Mode); nativeModes.push_back(CodecSrc::kStripe_Mode); nativeModes.push_back(CodecSrc::kCroppedScanline_Mode); supportsNativeScaling = true; break; - case SkEncodedFormat::kWEBP_SkEncodedFormat: + case SkEncodedImageFormat::kWEBP: nativeModes.push_back(CodecSrc::kSubset_Mode); supportsNativeScaling = true; break; - case SkEncodedFormat::kDNG_SkEncodedFormat: + case SkEncodedImageFormat::kDNG: break; default: nativeModes.push_back(CodecSrc::kScanline_Mode); @@ -547,7 +547,7 @@ static void push_codec_srcs(Path path) { switch (codec->getInfo().colorType()) { case kGray_8_SkColorType: colorTypes.push_back(CodecSrc::kGrayscale_Always_DstColorType); - if (kWBMP_SkEncodedFormat == codec->getEncodedFormat()) { + if (SkEncodedImageFormat::kWBMP == codec->getEncodedFormat()) { colorTypes.push_back(CodecSrc::kIndex8_Always_DstColorType); } break; @@ -640,15 +640,15 @@ static void push_codec_srcs(Path path) { push_image_gen_src(path, ImageGenSrc::kCodec_Mode, alphaType, false); #if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) - if (kWEBP_SkEncodedFormat != codec->getEncodedFormat() && - kWBMP_SkEncodedFormat != codec->getEncodedFormat() && + if (SkEncodedImageFormat::kWEBP != codec->getEncodedFormat() && + SkEncodedImageFormat::kWBMP != codec->getEncodedFormat() && kUnpremul_SkAlphaType != alphaType) { push_image_gen_src(path, ImageGenSrc::kPlatform_Mode, alphaType, false); } #elif defined(SK_BUILD_FOR_WIN) - if (kWEBP_SkEncodedFormat != codec->getEncodedFormat() && - kWBMP_SkEncodedFormat != codec->getEncodedFormat()) + if (SkEncodedImageFormat::kWEBP != codec->getEncodedFormat() && + SkEncodedImageFormat::kWBMP != codec->getEncodedFormat()) { push_image_gen_src(path, ImageGenSrc::kPlatform_Mode, alphaType, false); } diff --git a/fuzz/fuzz.cpp b/fuzz/fuzz.cpp index 377e53f656..b27eec988a 100644 --- a/fuzz/fuzz.cpp +++ b/fuzz/fuzz.cpp @@ -23,6 +23,8 @@ #include <signal.h> +#include "sk_tool_utils.h" + DEFINE_string2(bytes, b, "", "A path to a file. This can be the fuzz bytes or a binary to parse."); DEFINE_string2(name, n, "", "If --type is 'api', fuzz the API with this name."); @@ -122,7 +124,7 @@ int fuzz_api(sk_sp<SkData> bytes) { static void dump_png(SkBitmap bitmap) { if (!FLAGS_dump.isEmpty()) { - SkImageEncoder::EncodeFile(FLAGS_dump[0], bitmap, SkImageEncoder::kPNG_Type, 100); + sk_tool_utils::EncodeImageToFile(FLAGS_dump[0], bitmap, SkEncodedImageFormat::kPNG, 100); SkDebugf("Dumped to %s\n", FLAGS_dump[0]); } } diff --git a/gm/encode-platform.cpp b/gm/encode-platform.cpp index 09b64cce53..0357298711 100644 --- a/gm/encode-platform.cpp +++ b/gm/encode-platform.cpp @@ -6,10 +6,11 @@ */ #include "gm.h" + #include "Resources.h" #include "SkCanvas.h" #include "SkData.h" -#include "SkImageEncoder.h" +#include "SkImageEncoderPriv.h" #include "SkUnPreMultiply.h" namespace skiagm { @@ -36,18 +37,18 @@ static void make_unpremul_256(SkBitmap* bitmap) { bitmap->setAlphaType(kUnpremul_SkAlphaType); } -static SkImageEncoder* make_encoder(SkImageEncoder::Type type) { +static SkImageEncoder* make_encoder(SkEncodedImageFormat type) { #if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) - return CreateImageEncoder_CG(type); + return CreateImageEncoder_CG((SkImageEncoder::Type)type); #elif defined(SK_BUILD_FOR_WIN) - return CreateImageEncoder_WIC(type); + return CreateImageEncoder_WIC((SkImageEncoder::Type)type); #else switch (type) { - case SkImageEncoder::kPNG_Type: + case SkEncodedImageFormat::kPNG: return CreatePNGImageEncoder(); - case SkImageEncoder::kJPEG_Type: + case SkEncodedImageFormat::kJPEG: return CreateJPEGImageEncoder(); - case SkImageEncoder::kWEBP_Type: + case SkEncodedImageFormat::kWEBP: return CreateWEBPImageEncoder(); default: SkASSERT(false); @@ -57,24 +58,28 @@ static SkImageEncoder* make_encoder(SkImageEncoder::Type type) { } #if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) -static SkImageEncoder::Type kTypes[] { - SkImageEncoder::kPNG_Type, SkImageEncoder::kJPEG_Type, SkImageEncoder::kGIF_Type, - SkImageEncoder::kBMP_Type, SkImageEncoder::kICO_Type, +static SkEncodedImageFormat kTypes[] { + SkEncodedImageFormat::kPNG, SkEncodedImageFormat::kJPEG, SkEncodedImageFormat::kGIF, + SkEncodedImageFormat::kBMP, SkEncodedImageFormat::kICO, }; #elif defined(SK_BUILD_FOR_WIN) // Use PNG multiple times because our WIC encoder does not support GIF, BMP, or ICO. -static SkImageEncoder::Type kTypes[] { - SkImageEncoder::kPNG_Type, SkImageEncoder::kJPEG_Type, SkImageEncoder::kPNG_Type, - SkImageEncoder::kPNG_Type, SkImageEncoder::kPNG_Type, +static SkEncodedImageFormat kTypes[] { + SkEncodedImageFormat::kPNG, SkEncodedImageFormat::kJPEG, SkEncodedImageFormat::kPNG, + SkEncodedImageFormat::kPNG, SkEncodedImageFormat::kPNG, }; #else // Use WEBP in place of GIF. Use PNG two extra times. We don't support GIF, BMP, or ICO. -static SkImageEncoder::Type kTypes[] { - SkImageEncoder::kPNG_Type, SkImageEncoder::kJPEG_Type, SkImageEncoder::kWEBP_Type, - SkImageEncoder::kPNG_Type, SkImageEncoder::kPNG_Type, +static SkEncodedImageFormat kTypes[] { + SkEncodedImageFormat::kPNG, SkEncodedImageFormat::kJPEG, SkEncodedImageFormat::kWEBP, + SkEncodedImageFormat::kPNG, SkEncodedImageFormat::kPNG, }; #endif +static sk_sp<SkData> encode_data(std::unique_ptr<SkImageEncoder>& encoder, const SkBitmap& src) { + SkDynamicMemoryWStream buffer; + return encoder->encodeStream(&buffer, src, 100) ? buffer.detachAsData() : nullptr; +} class EncodePlatformGM : public GM { public: @@ -95,15 +100,12 @@ protected: make_premul_256(&premulBm); make_unpremul_256(&unpremulBm); - for (SkImageEncoder::Type type : kTypes) { + for (SkEncodedImageFormat type : kTypes) { std::unique_ptr<SkImageEncoder> encoder(make_encoder(type)); - sk_sp<SkData> opaqueData(encoder->encodeData(opaqueBm, 100)); - sk_sp<SkData> premulData(encoder->encodeData(premulBm, 100)); - sk_sp<SkData> unpremulData(encoder->encodeData(unpremulBm, 100)); - sk_sp<SkImage> opaqueImage = SkImage::MakeFromEncoded(opaqueData); - sk_sp<SkImage> premulImage = SkImage::MakeFromEncoded(premulData); - sk_sp<SkImage> unpremulImage = SkImage::MakeFromEncoded(unpremulData); + auto opaqueImage = SkImage::MakeFromEncoded(encode_data(encoder, opaqueBm)); + auto premulImage = SkImage::MakeFromEncoded(encode_data(encoder, premulBm)); + auto unpremulImage = SkImage::MakeFromEncoded(encode_data(encoder, unpremulBm)); canvas->drawImage(opaqueImage.get(), 0.0f, 0.0f); canvas->drawImage(premulImage.get(), 0.0f, 256.0f); diff --git a/gm/encode.cpp b/gm/encode.cpp index 0cd562a358..d4598d0134 100644 --- a/gm/encode.cpp +++ b/gm/encode.cpp @@ -28,8 +28,8 @@ protected: void onDraw(SkCanvas* canvas) override { SkBitmap orig; GetResourceAsBitmap("mandrill_512_q075.jpg", &orig); - sk_sp<SkData> pngData(SkImageEncoder::EncodeData(orig, SkImageEncoder::kPNG_Type, 100)); - sk_sp<SkData> jpegData(SkImageEncoder::EncodeData(orig, SkImageEncoder::kJPEG_Type, 100)); + sk_sp<SkData> pngData(sk_tool_utils::EncodeImageToData(orig, SkEncodedImageFormat::kPNG, 100)); + sk_sp<SkData> jpegData(sk_tool_utils::EncodeImageToData(orig, SkEncodedImageFormat::kJPEG, 100)); sk_sp<SkImage> pngImage = SkImage::MakeFromEncoded(pngData); sk_sp<SkImage> jpegImage = SkImage::MakeFromEncoded(jpegData); diff --git a/gm/image.cpp b/gm/image.cpp index 5454ac3966..6545c0a5f4 100644 --- a/gm/image.cpp +++ b/gm/image.cpp @@ -348,13 +348,13 @@ static SkImageGenerator* gen_picture(const SkImageInfo& info) { static SkImageGenerator* gen_png(const SkImageInfo& info) { sk_sp<SkImage> image(make_raster(info, nullptr, draw_opaque_contents)); - sk_sp<SkData> data(image->encode(SkImageEncoder::kPNG_Type, 100)); + sk_sp<SkData> data(image->encode(SkEncodedImageFormat::kPNG, 100)); return SkImageGenerator::NewFromEncoded(data.get()); } static SkImageGenerator* gen_jpg(const SkImageInfo& info) { sk_sp<SkImage> image(make_raster(info, nullptr, draw_opaque_contents)); - sk_sp<SkData> data(image->encode(SkImageEncoder::kJPEG_Type, 100)); + sk_sp<SkData> data(image->encode(SkEncodedImageFormat::kJPEG, 100)); return SkImageGenerator::NewFromEncoded(data.get()); } @@ -467,7 +467,7 @@ DEF_SIMPLE_GM(new_texture_image, canvas, 225, 60) { // Create encoded image. [bmp] { sk_sp<SkData> src( - SkImageEncoder::EncodeData(bmp, SkImageEncoder::kPNG_Type, 100)); + sk_tool_utils::EncodeImageToData(bmp, SkEncodedImageFormat::kPNG, 100)); return SkImage::MakeFromEncoded(std::move(src)); }, // Create a picture image. diff --git a/gm/image_shader.cpp b/gm/image_shader.cpp index 924199e6e7..49b1ed524c 100644 --- a/gm/image_shader.cpp +++ b/gm/image_shader.cpp @@ -55,7 +55,7 @@ static sk_sp<SkImage> make_encode_gen(GrContext* ctx, SkPicture* pic, const SkIm if (!src) { return nullptr; } - sk_sp<SkData> encoded(src->encode(SkImageEncoder::kPNG_Type, 100)); + sk_sp<SkData> encoded(src->encode(SkEncodedImageFormat::kPNG, 100)); if (!encoded) { return nullptr; } diff --git a/gn/android_framework_defines.gni b/gn/android_framework_defines.gni index 90fea2fb25..a80e38d09e 100644 --- a/gn/android_framework_defines.gni +++ b/gn/android_framework_defines.gni @@ -14,5 +14,6 @@ android_framework_defines = [ "SK_IGNORE_GPU_DITHER", "SK_SUPPORT_LEGACY_CANVAS_IS_REFCNT", "SK_SUPPORT_LEGACY_CLIP_REGIONOPS", + "SK_SUPPORT_LEGACY_IMAGE_ENCODER_CLASS", "SK_SUPPORT_LEGACY_SHADER_ISABITMAP", ] diff --git a/include/codec/SkAndroidCodec.h b/include/codec/SkAndroidCodec.h index 07d1b135aa..ee9d0f36d7 100644 --- a/include/codec/SkAndroidCodec.h +++ b/include/codec/SkAndroidCodec.h @@ -51,7 +51,7 @@ public: /** * Format of the encoded data. */ - SkEncodedFormat getEncodedFormat() const { return fCodec->getEncodedFormat(); } + SkEncodedFormat getEncodedFormat() const { return (SkEncodedFormat)fCodec->getEncodedFormat(); } /** * @param requestedColorType Color type requested by the client @@ -154,7 +154,7 @@ public: * * Must be within the bounds returned by getInfo(). * - * If the EncodedFormat is kWEBP_SkEncodedFormat, the top and left + * If the EncodedFormat is SkEncodedImageFormat::kWEBP, the top and left * values must be even. * * The default is NULL, meaning a decode of the entire image. diff --git a/include/codec/SkCodec.h b/include/codec/SkCodec.h index d5280b4833..ebc2b9ab1f 100644 --- a/include/codec/SkCodec.h +++ b/include/codec/SkCodec.h @@ -10,7 +10,7 @@ #include "../private/SkTemplates.h" #include "SkColor.h" -#include "SkEncodedFormat.h" +#include "SkEncodedImageFormat.h" #include "SkEncodedInfo.h" #include "SkImageInfo.h" #include "SkSize.h" @@ -176,7 +176,7 @@ public: /** * Format of the encoded data. */ - SkEncodedFormat getEncodedFormat() const { return this->onGetEncodedFormat(); } + SkEncodedImageFormat getEncodedFormat() const { return this->onGetEncodedFormat(); } /** * Used to describe the result of a call to getPixels(). @@ -255,7 +255,7 @@ public: /** * If not NULL, represents a subset of the original image to decode. * Must be within the bounds returned by getInfo(). - * If the EncodedFormat is kWEBP_SkEncodedFormat (the only one which + * If the EncodedFormat is SkEncodedImageFormat::kWEBP (the only one which * currently supports subsets), the top and left values must be even. * * In getPixels and incremental decode, we will attempt to decode the @@ -667,7 +667,7 @@ protected: return false; } - virtual SkEncodedFormat onGetEncodedFormat() const = 0; + virtual SkEncodedImageFormat onGetEncodedFormat() const = 0; /** * @param rowsDecoded When the encoded image stream is incomplete, this function diff --git a/include/codec/SkEncodedFormat.h b/include/codec/SkEncodedFormat.h index c097e088f2..485bff181a 100644 --- a/include/codec/SkEncodedFormat.h +++ b/include/codec/SkEncodedFormat.h @@ -8,21 +8,29 @@ #ifndef SkEncodedFormat_DEFINED #define SkEncodedFormat_DEFINED -/** - * Enum describing format of encoded data. - */ +#include "SkEncodedImageFormat.h" +#include "SkTypes.h" + +#ifdef SK_SUPPORT_LEGACY_IMAGE_ENCODER_CLASS + enum SkEncodedFormat { - kUnknown_SkEncodedFormat, - kBMP_SkEncodedFormat, - kGIF_SkEncodedFormat, - kICO_SkEncodedFormat, - kJPEG_SkEncodedFormat, - kPNG_SkEncodedFormat, - kWBMP_SkEncodedFormat, - kWEBP_SkEncodedFormat, - kPKM_SkEncodedFormat, - kKTX_SkEncodedFormat, - kASTC_SkEncodedFormat, - kDNG_SkEncodedFormat, + kBMP_SkEncodedFormat = (int)SkEncodedImageFormat::kBMP, + kGIF_SkEncodedFormat = (int)SkEncodedImageFormat::kGIF, + kICO_SkEncodedFormat = (int)SkEncodedImageFormat::kICO, + kJPEG_SkEncodedFormat = (int)SkEncodedImageFormat::kJPEG, + kPNG_SkEncodedFormat = (int)SkEncodedImageFormat::kPNG, + kWBMP_SkEncodedFormat = (int)SkEncodedImageFormat::kWBMP, + kWEBP_SkEncodedFormat = (int)SkEncodedImageFormat::kWEBP, + kPKM_SkEncodedFormat = (int)SkEncodedImageFormat::kPKM, + kKTX_SkEncodedFormat = (int)SkEncodedImageFormat::kKTX, + kASTC_SkEncodedFormat = (int)SkEncodedImageFormat::kASTC, + kDNG_SkEncodedFormat = (int)SkEncodedImageFormat::kDNG, }; + +#else + +typedef SkEncodedImageFormat SkEncodedFormat; + +#endif // SK_SUPPORT_LEGACY_IMAGE_ENCODER_CLASS + #endif // SkEncodedFormat_DEFINED diff --git a/include/core/SkEncodedImageFormat.h b/include/core/SkEncodedImageFormat.h new file mode 100644 index 0000000000..8f79236689 --- /dev/null +++ b/include/core/SkEncodedImageFormat.h @@ -0,0 +1,33 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkEncodedImageFormat_DEFINED +#define SkEncodedImageFormat_DEFINED + +#include <stdint.h> + +/** + * Enum describing format of encoded data. + */ +enum class SkEncodedImageFormat { +#ifdef GOOGLE3 + kUnknown, +#endif + kBMP, + kGIF, + kICO, + kJPEG, + kPNG, + kWBMP, + kWEBP, + kPKM, + kKTX, + kASTC, + kDNG, +}; + +#endif // SkEncodedImageFormat_DEFINED diff --git a/include/core/SkImage.h b/include/core/SkImage.h index 02b632bc65..625d0a0b63 100644 --- a/include/core/SkImage.h +++ b/include/core/SkImage.h @@ -275,7 +275,12 @@ public: * Note: this will attempt to encode the image's pixels in the specified format, * even if the image returns a data from refEncoded(). That data will be ignored. */ - SkData* encode(SkImageEncoder::Type, int quality) const; + SkData* encode(SkEncodedImageFormat, int quality) const; +#ifdef SK_SUPPORT_LEGACY_IMAGE_ENCODER_CLASS + SkData* encode(SkImageEncoder::Type t, int quality) const { + return this->encode((SkEncodedImageFormat)t, quality); + } +#endif /** * Encode the image and return the result as a caller-managed SkData. This will diff --git a/include/core/SkImageEncoder.h b/include/core/SkImageEncoder.h index 7d15250917..41cdb38f38 100644 --- a/include/core/SkImageEncoder.h +++ b/include/core/SkImageEncoder.h @@ -8,32 +8,61 @@ #ifndef SkImageEncoder_DEFINED #define SkImageEncoder_DEFINED -#include "SkImageInfo.h" +#include "SkBitmap.h" +#include "SkEncodedImageFormat.h" +#include "SkPixelSerializer.h" +#include "SkStream.h" #include "SkTRegistry.h" -class SkBitmap; -class SkPixelSerializer; -class SkPixmap; -class SkData; -class SkWStream; +/** + * Encode SkPixmap in the given binary image format. + * + * @param dst results are written to this stream. + * @param src source pixels. + * @param format image format, not all formats are supported. + * @param quality range from 0-100, not all formats respect quality. + * + * @return false iff input is bad or format is unsupported. + * + * Will always return false if Skia is compiled without image + * encoders. + * + * For examples of encoding an image to a file or to a block of memory, + * see tools/sk_tool_utils.h. + */ +SK_API bool SkEncodeImage(SkWStream* dst, const SkPixmap& src, + SkEncodedImageFormat format, int quality); +/** + * The following helper function wraps SkEncodeImage(). + */ +inline bool SkEncodeImage(SkWStream* dst, const SkBitmap& src, SkEncodedImageFormat f, int q) { + SkAutoLockPixels autoLockPixels(src); + SkPixmap pixmap; + return src.peekPixels(&pixmap) && SkEncodeImage(dst, pixmap, f, q); +} + +#ifdef SK_SUPPORT_LEGACY_IMAGE_ENCODER_CLASS + +//////////////////////////////////////////////////////////////////////////////// class SkImageEncoder { public: - // TODO (scroggo): Merge with SkEncodedFormat. enum Type { - kUnknown_Type, - kBMP_Type, - kGIF_Type, - kICO_Type, - kJPEG_Type, - kPNG_Type, - kWBMP_Type, - kWEBP_Type, - kKTX_Type, +#ifdef GOOGLE3 + kUnknown_Type = (int)SkEncodedImageFormat::kUnknown, +#endif + kBMP_Type = (int)SkEncodedImageFormat::kBMP, + kGIF_Type = (int)SkEncodedImageFormat::kGIF, + kICO_Type = (int)SkEncodedImageFormat::kICO, + kJPEG_Type = (int)SkEncodedImageFormat::kJPEG, + kPNG_Type = (int)SkEncodedImageFormat::kPNG, + kWBMP_Type = (int)SkEncodedImageFormat::kWBMP, + kWEBP_Type = (int)SkEncodedImageFormat::kWEBP, + kKTX_Type = (int)SkEncodedImageFormat::kKTX, }; static SkImageEncoder* Create(Type); - virtual ~SkImageEncoder(); + virtual ~SkImageEncoder() {} /* Quality ranges from 0..100 */ enum { @@ -46,36 +75,57 @@ public: * encoded, return null. On success, the caller is responsible for * calling unref() on the data when they are finished. */ - SkData* encodeData(const SkBitmap&, int quality); + SkData* encodeData(const SkBitmap& bm, int quality) { + SkDynamicMemoryWStream buffer; + return this->encodeStream(&buffer, bm, quality) + ? buffer.detachAsData().release() + : nullptr; + } /** * Encode bitmap 'bm' in the desired format, writing results to * file 'file', at quality level 'quality' (which can be in range * 0-100). Returns false on failure. */ - bool encodeFile(const char file[], const SkBitmap& bm, int quality); + bool encodeFile(const char path[], const SkBitmap& bm, int quality) { + SkFILEWStream file(path); + return this->encodeStream(&file, bm, quality); + } /** * Encode bitmap 'bm' in the desired format, writing results to * stream 'stream', at quality level 'quality' (which can be in * range 0-100). Returns false on failure. */ - bool encodeStream(SkWStream* stream, const SkBitmap& bm, int quality); - - static SkData* EncodeData(const SkImageInfo&, const void* pixels, size_t rowBytes, - 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(); + bool encodeStream(SkWStream* dst, const SkBitmap& src, int quality) { + return this->onEncode(dst, src, SkMin32(100, SkMax32(0, quality))); + } + + static SkData* EncodeData(const SkImageInfo& info, const void* pixels, size_t rowBytes, + Type t, int quality) { + SkPixmap pixmap(info, pixels, rowBytes, nullptr); + return SkImageEncoder::EncodeData(pixmap, t, quality); + } + + static SkData* EncodeData(const SkBitmap& src, Type t, int quality) { + SkDynamicMemoryWStream buf; + return SkEncodeImage(&buf, src, (SkEncodedImageFormat)t, quality) + ? buf.detachAsData().release() : nullptr; + } + + static SkData* EncodeData(const SkPixmap& pixmap, Type t, int quality) { + SkDynamicMemoryWStream buf; + return SkEncodeImage(&buf, pixmap, (SkEncodedImageFormat)t, quality) + ? buf.detachAsData().release() : nullptr; + } + + static bool EncodeFile(const char path[], const SkBitmap& src, Type t, int quality) { + SkFILEWStream file(path); + return SkEncodeImage(&file, src, (SkEncodedImageFormat)t, quality); + } + static bool EncodeStream(SkWStream* dst, const SkBitmap& bm, Type t, int quality) { + return SkEncodeImage(dst, bm, (SkEncodedImageFormat)t, quality); + } protected: /** @@ -88,32 +138,5 @@ protected: virtual bool onEncode(SkWStream* stream, const SkBitmap& bm, int quality) = 0; }; -// This macro declares a global (i.e., non-class owned) creation entry point -// for each encoder (e.g., CreateJPEGImageEncoder) -#define DECLARE_ENCODER_CREATOR(codec) \ - SK_API SkImageEncoder *Create ## codec (); - -// This macro defines the global creation entry point for each encoder. Each -// encoder implementation that registers with the encoder factory must call it. -#define DEFINE_ENCODER_CREATOR(codec) \ - SkImageEncoder* Create##codec() { return new Sk##codec; } - -// All the encoders known by Skia. Note that, depending on the compiler settings, -// not all of these will be available -DECLARE_ENCODER_CREATOR(JPEGImageEncoder); -DECLARE_ENCODER_CREATOR(PNGImageEncoder); -DECLARE_ENCODER_CREATOR(KTXImageEncoder); -DECLARE_ENCODER_CREATOR(WEBPImageEncoder); - -#if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) -SkImageEncoder* CreateImageEncoder_CG(SkImageEncoder::Type type); -#endif - -#if defined(SK_BUILD_FOR_WIN) -SkImageEncoder* CreateImageEncoder_WIC(SkImageEncoder::Type type); -#endif - -// Typedef to make registering encoder callback easier -// This has to be defined outside SkImageEncoder. :( -typedef SkTRegistry<SkImageEncoder*(*)(SkImageEncoder::Type)> SkImageEncoder_EncodeReg; -#endif +#endif // SK_SUPPORT_LEGACY_IMAGE_ENCODER_CLASS +#endif // SkImageEncoder_DEFINED diff --git a/public.bzl b/public.bzl index 55f40f8778..970d7566ba 100644 --- a/public.bzl +++ b/public.bzl @@ -484,6 +484,7 @@ DM_INCLUDES = [ "src/effects", "src/effects/gradients", "src/fonts", + "src/images", "src/pathops", "src/pipe/utils", "src/ports", @@ -600,6 +601,7 @@ DEFINES_ALL = [ "SK_SUPPORT_LEGACY_ACCESSBITMAP", "SK_SUPPORT_LEGACY_CLIP_REGIONOPS", "SK_SUPPORT_LEGACY_XFERMODE_IS_PUBLIC", + "SK_SUPPORT_LEGACY_IMAGE_ENCODER_CLASS", # Temporarily Disable analytic AA for Google3 "SK_NO_ANALYTIC_AA", ] diff --git a/samplecode/SampleApp.cpp b/samplecode/SampleApp.cpp index 8a5927fcc3..a8c2e0b113 100644 --- a/samplecode/SampleApp.cpp +++ b/samplecode/SampleApp.cpp @@ -1407,8 +1407,8 @@ void SampleWindow::afterChildren(SkCanvas* orig) { static int gSampleGrabCounter; SkString name; name.printf("sample_grab_%d.png", gSampleGrabCounter++); - SkImageEncoder::EncodeFile(name.c_str(), bmp, - SkImageEncoder::kPNG_Type, 100); + sk_tool_utils::EncodeImageToFile(name.c_str(), bmp, + SkEncodedImageFormat::kPNG, 100); } this->inval(nullptr); return; diff --git a/samplecode/SampleSlides.cpp b/samplecode/SampleSlides.cpp index 43221d41a7..c1c49b4ab1 100644 --- a/samplecode/SampleSlides.cpp +++ b/samplecode/SampleSlides.cpp @@ -15,6 +15,8 @@ #include "SkPaint.h" #include "SkView.h" +#include "sk_tool_utils.h" + #define BG_COLOR 0xFFDDDDDD typedef void (*SlideProc)(SkCanvas*); @@ -681,7 +683,7 @@ public: canvas.restore(); SkString str; str.printf("/skimages/slide_" SK_SIZE_T_SPECIFIER ".png", i); - SkImageEncoder::EncodeFile(str.c_str(), bm, SkImageEncoder::kPNG_Type, 100); + sk_tool_utils::EncodeImageToFile(str.c_str(), bm, SkEncodedImageFormat::kPNG, 100); } this->setBGColor(BG_COLOR); } diff --git a/src/android/SkBitmapRegionCodec.h b/src/android/SkBitmapRegionCodec.h index 5c59d52d71..2c9536c109 100644 --- a/src/android/SkBitmapRegionCodec.h +++ b/src/android/SkBitmapRegionCodec.h @@ -26,7 +26,9 @@ public: bool conversionSupported(SkColorType colorType) override; - SkEncodedFormat getEncodedFormat() override { return fCodec->getEncodedFormat(); } + SkEncodedFormat getEncodedFormat() override { + return (SkEncodedFormat)fCodec->getEncodedFormat(); + } private: diff --git a/src/android/SkBitmapRegionDecoder.cpp b/src/android/SkBitmapRegionDecoder.cpp index 15a530e21a..8298fb5298 100644 --- a/src/android/SkBitmapRegionDecoder.cpp +++ b/src/android/SkBitmapRegionDecoder.cpp @@ -29,11 +29,10 @@ SkBitmapRegionDecoder* SkBitmapRegionDecoder::Create( return NULL; } - SkEncodedFormat format = codec->getEncodedFormat(); - switch (format) { - case SkEncodedFormat::kJPEG_SkEncodedFormat: - case SkEncodedFormat::kPNG_SkEncodedFormat: - case SkEncodedFormat::kWEBP_SkEncodedFormat: + switch ((SkEncodedImageFormat)codec->getEncodedFormat()) { + case SkEncodedImageFormat::kJPEG: + case SkEncodedImageFormat::kPNG: + case SkEncodedImageFormat::kWEBP: break; default: return nullptr; diff --git a/src/animator/SkSnapshot.cpp b/src/animator/SkSnapshot.cpp index fbaedff730..6be1a53471 100644 --- a/src/animator/SkSnapshot.cpp +++ b/src/animator/SkSnapshot.cpp @@ -30,7 +30,7 @@ DEFINE_GET_MEMBER(SkSnapshot); SkSnapshot::SkSnapshot() { quality = 100 * SK_Scalar1; - type = (SkImageEncoder::Type) -1; + type = (SkEncodedImageFormat) -1; sequence = false; fSeqVal = 0; } @@ -38,7 +38,7 @@ SkSnapshot::SkSnapshot() bool SkSnapshot::draw(SkAnimateMaker& maker) { SkASSERT(type >= 0); SkASSERT(filename.size() > 0); - SkImageEncoder* encoder = SkImageEncoder::Create((SkImageEncoder::Type) type); + SkImageEncoder* encoder = SkImageEncoder::Create((SkEncodedImageFormat) type); if (!encoder) { return false; } @@ -54,9 +54,9 @@ bool SkSnapshot::draw(SkAnimateMaker& maker) { if (++fSeqVal > 999) sequence = false; } - if (type == SkImageEncoder::kJPEG_Type) + if (type == SkEncodedImageFormat::kJPEG) name.append(".jpg"); - else if (type == SkImageEncoder::kPNG_Type) + else if (type == SkEncodedImageFormat::kPNG) name.append(".png"); SkBitmap pixels; diff --git a/src/animator/SkSnapshot.h b/src/animator/SkSnapshot.h index 003a9dc796..a802d9903d 100644 --- a/src/animator/SkSnapshot.h +++ b/src/animator/SkSnapshot.h @@ -22,7 +22,7 @@ class SkSnapshot: public SkADrawable { SkString filename; SkScalar quality; SkBool sequence; - int /*SkImageEncoder::Type*/ type; + int /*SkEncodedImageFormat*/ type; int fSeqVal; }; diff --git a/src/codec/SkAndroidCodec.cpp b/src/codec/SkAndroidCodec.cpp index 01605b2669..c315b032fb 100644 --- a/src/codec/SkAndroidCodec.cpp +++ b/src/codec/SkAndroidCodec.cpp @@ -28,24 +28,24 @@ SkAndroidCodec* SkAndroidCodec::NewFromStream(SkStream* stream, SkPngChunkReader return nullptr; } - switch (codec->getEncodedFormat()) { + switch ((SkEncodedImageFormat)codec->getEncodedFormat()) { #ifdef SK_HAS_PNG_LIBRARY - case kPNG_SkEncodedFormat: - case kICO_SkEncodedFormat: + case SkEncodedImageFormat::kPNG: + case SkEncodedImageFormat::kICO: #endif #ifdef SK_HAS_JPEG_LIBRARY - case kJPEG_SkEncodedFormat: + case SkEncodedImageFormat::kJPEG: #endif - case kGIF_SkEncodedFormat: - case kBMP_SkEncodedFormat: - case kWBMP_SkEncodedFormat: + case SkEncodedImageFormat::kGIF: + case SkEncodedImageFormat::kBMP: + case SkEncodedImageFormat::kWBMP: return new SkSampledCodec(codec.release()); #ifdef SK_HAS_WEBP_LIBRARY - case kWEBP_SkEncodedFormat: + case SkEncodedImageFormat::kWEBP: return new SkWebpAdapterCodec((SkWebpCodec*) codec.release()); #endif #ifdef SK_CODEC_DECODES_RAW - case kDNG_SkEncodedFormat: + case SkEncodedImageFormat::kDNG: return new SkRawAdapterCodec((SkRawCodec*)codec.release()); #endif default: @@ -64,8 +64,8 @@ SkAndroidCodec* SkAndroidCodec::NewFromData(sk_sp<SkData> data, SkPngChunkReader SkColorType SkAndroidCodec::computeOutputColorType(SkColorType requestedColorType) { // The legacy GIF and WBMP decoders always decode to kIndex_8_SkColorType. // We will maintain this behavior. - SkEncodedFormat format = this->getEncodedFormat(); - if (kGIF_SkEncodedFormat == format || kWBMP_SkEncodedFormat == format) { + SkEncodedImageFormat format = (SkEncodedImageFormat)this->getEncodedFormat(); + if (SkEncodedImageFormat::kGIF == format || SkEncodedImageFormat::kWBMP == format) { return kIndex_8_SkColorType; } diff --git a/src/codec/SkBmpCodec.h b/src/codec/SkBmpCodec.h index 0e38c84059..75740f76ff 100644 --- a/src/codec/SkBmpCodec.h +++ b/src/codec/SkBmpCodec.h @@ -41,7 +41,7 @@ protected: SkBmpCodec(int width, int height, const SkEncodedInfo& info, SkStream* stream, uint16_t bitsPerPixel, SkCodec::SkScanlineOrder rowOrder); - SkEncodedFormat onGetEncodedFormat() const override { return kBMP_SkEncodedFormat; } + SkEncodedImageFormat onGetEncodedFormat() const override { return SkEncodedImageFormat::kBMP; } /* * Read enough of the stream to initialize the SkBmpCodec. Returns a bool diff --git a/src/codec/SkGifCodec.h b/src/codec/SkGifCodec.h index 8e93730bcd..9e980abafa 100644 --- a/src/codec/SkGifCodec.h +++ b/src/codec/SkGifCodec.h @@ -40,8 +40,8 @@ protected: Result onGetPixels(const SkImageInfo&, void*, size_t, const Options&, SkPMColor*, int*, int*) override; - SkEncodedFormat onGetEncodedFormat() const override { - return kGIF_SkEncodedFormat; + SkEncodedImageFormat onGetEncodedFormat() const override { + return SkEncodedImageFormat::kGIF; } bool onRewind() override; diff --git a/src/codec/SkIcoCodec.h b/src/codec/SkIcoCodec.h index 0c4e504a19..e8dcc83f59 100644 --- a/src/codec/SkIcoCodec.h +++ b/src/codec/SkIcoCodec.h @@ -39,8 +39,8 @@ protected: Result onGetPixels(const SkImageInfo& dstInfo, void* dst, size_t dstRowBytes, const Options&, SkPMColor*, int*, int*) override; - SkEncodedFormat onGetEncodedFormat() const override { - return kICO_SkEncodedFormat; + SkEncodedImageFormat onGetEncodedFormat() const override { + return SkEncodedImageFormat::kICO; } SkScanlineOrder onGetScanlineOrder() const override; diff --git a/src/codec/SkJpegCodec.h b/src/codec/SkJpegCodec.h index 9e08c869cf..9a34aa6a26 100644 --- a/src/codec/SkJpegCodec.h +++ b/src/codec/SkJpegCodec.h @@ -51,8 +51,8 @@ protected: Result onGetYUV8Planes(const SkYUVSizeInfo& sizeInfo, void* planes[3]) override; - SkEncodedFormat onGetEncodedFormat() const override { - return kJPEG_SkEncodedFormat; + SkEncodedImageFormat onGetEncodedFormat() const override { + return SkEncodedImageFormat::kJPEG; } bool onRewind() override; diff --git a/src/codec/SkPngCodec.h b/src/codec/SkPngCodec.h index 590a631a20..c246887cfc 100644 --- a/src/codec/SkPngCodec.h +++ b/src/codec/SkPngCodec.h @@ -9,7 +9,7 @@ #include "SkColorSpaceXform.h" #include "SkColorTable.h" #include "SkPngChunkReader.h" -#include "SkEncodedFormat.h" +#include "SkEncodedImageFormat.h" #include "SkImageInfo.h" #include "SkRefCnt.h" #include "SkSwizzler.h" @@ -51,7 +51,7 @@ protected: Result onGetPixels(const SkImageInfo&, void*, size_t, const Options&, SkPMColor*, int*, int*) override; - SkEncodedFormat onGetEncodedFormat() const override { return kPNG_SkEncodedFormat; } + SkEncodedImageFormat onGetEncodedFormat() const override { return SkEncodedImageFormat::kPNG; } bool onRewind() override; uint64_t onGetFillValue(const SkImageInfo&) const override; diff --git a/src/codec/SkRawAdapterCodec.h b/src/codec/SkRawAdapterCodec.h index b552f2aaea..8777180ec2 100644 --- a/src/codec/SkRawAdapterCodec.h +++ b/src/codec/SkRawAdapterCodec.h @@ -10,7 +10,7 @@ #include "SkAndroidCodec.h" #include "SkCodec.h" -#include "SkEncodedFormat.h" +#include "SkEncodedImageFormat.h" #include "SkRawCodec.h" #include "SkStream.h" #include "SkTypes.h" diff --git a/src/codec/SkRawCodec.h b/src/codec/SkRawCodec.h index 75654c7e10..51bb234b73 100644 --- a/src/codec/SkRawCodec.h +++ b/src/codec/SkRawCodec.h @@ -37,8 +37,8 @@ protected: Result onGetPixels(const SkImageInfo& dstInfo, void* dst, size_t dstRowBytes, const Options&, SkPMColor*, int*, int*) override; - SkEncodedFormat onGetEncodedFormat() const override { - return kDNG_SkEncodedFormat; + SkEncodedImageFormat onGetEncodedFormat() const override { + return SkEncodedImageFormat::kDNG; } SkISize onGetScaledDimensions(float desiredScale) const override; diff --git a/src/codec/SkSampledCodec.cpp b/src/codec/SkSampledCodec.cpp index e70aadeabf..1d9953bb79 100644 --- a/src/codec/SkSampledCodec.cpp +++ b/src/codec/SkSampledCodec.cpp @@ -26,7 +26,7 @@ SkISize SkSampledCodec::accountForNativeScaling(int* sampleSizePtr, int* nativeS } // Only JPEG supports native downsampling. - if (this->codec()->getEncodedFormat() == kJPEG_SkEncodedFormat) { + if (this->codec()->getEncodedFormat() == SkEncodedImageFormat::kJPEG) { // See if libjpeg supports this scale directly switch (sampleSize) { case 2: diff --git a/src/codec/SkWbmpCodec.cpp b/src/codec/SkWbmpCodec.cpp index 19c8c7db37..6356e30536 100644 --- a/src/codec/SkWbmpCodec.cpp +++ b/src/codec/SkWbmpCodec.cpp @@ -113,8 +113,8 @@ SkWbmpCodec::SkWbmpCodec(int width, int height, const SkEncodedInfo& info, SkStr , fColorTable(nullptr) {} -SkEncodedFormat SkWbmpCodec::onGetEncodedFormat() const { - return kWBMP_SkEncodedFormat; +SkEncodedImageFormat SkWbmpCodec::onGetEncodedFormat() const { + return SkEncodedImageFormat::kWBMP; } SkCodec::Result SkWbmpCodec::onGetPixels(const SkImageInfo& info, diff --git a/src/codec/SkWbmpCodec.h b/src/codec/SkWbmpCodec.h index 6946ea0a66..40f507e9f3 100644 --- a/src/codec/SkWbmpCodec.h +++ b/src/codec/SkWbmpCodec.h @@ -24,7 +24,7 @@ public: static SkCodec* NewFromStream(SkStream*); protected: - SkEncodedFormat onGetEncodedFormat() const override; + SkEncodedImageFormat onGetEncodedFormat() const override; Result onGetPixels(const SkImageInfo&, void*, size_t, const Options&, SkPMColor[], int*, int*) override; bool onRewind() override; diff --git a/src/codec/SkWebpCodec.h b/src/codec/SkWebpCodec.h index b9c493f204..93b60f646e 100644 --- a/src/codec/SkWebpCodec.h +++ b/src/codec/SkWebpCodec.h @@ -10,7 +10,7 @@ #include "SkCodec.h" #include "SkColorSpace.h" -#include "SkEncodedFormat.h" +#include "SkEncodedImageFormat.h" #include "SkImageInfo.h" #include "SkTypes.h" @@ -30,7 +30,7 @@ public: protected: Result onGetPixels(const SkImageInfo&, void*, size_t, const Options&, SkPMColor*, int*, int*) override; - SkEncodedFormat onGetEncodedFormat() const override { return kWEBP_SkEncodedFormat; } + SkEncodedImageFormat onGetEncodedFormat() const override { return SkEncodedImageFormat::kWEBP; } SkISize onGetScaledDimensions(float desiredScale) const override; diff --git a/src/gpu/GrSurface.cpp b/src/gpu/GrSurface.cpp index f67bfd4eb5..3bb666e427 100644 --- a/src/gpu/GrSurface.cpp +++ b/src/gpu/GrSurface.cpp @@ -165,6 +165,11 @@ bool GrSurface::readPixels(int left, int top, int width, int height, rowBytes, pixelOpsFlags); } +static bool encode_image_to_file(const char* path, const SkBitmap& src) { + SkFILEWStream file(path); + return file.isValid() && SkEncodeImage(&file, src, SkEncodedImageFormat::kPNG, 100); +} + // TODO: This should probably be a non-member helper function. It might only be needed in // debug or developer builds. bool GrSurface::savePixels(const char* filename) { @@ -183,7 +188,7 @@ bool GrSurface::savePixels(const char* filename) { // remove any previous version of this file remove(filename); - if (!SkImageEncoder::EncodeFile(filename, bm, SkImageEncoder::kPNG_Type, 100)) { + if (!encode_image_to_file(filename, bm)) { SkDebugf("------ failed to encode %s\n", filename); remove(filename); // remove any partial file return false; diff --git a/src/image/SkImage.cpp b/src/image/SkImage.cpp index 3487b7d927..e0436815a7 100644 --- a/src/image/SkImage.cpp +++ b/src/image/SkImage.cpp @@ -103,27 +103,22 @@ sk_sp<SkShader> SkImage::makeShader(SkShader::TileMode tileX, SkShader::TileMode return SkImageShader::Make(sk_ref_sp(const_cast<SkImage*>(this)), tileX, tileY, localMatrix); } -SkData* SkImage::encode(SkImageEncoder::Type type, int quality) const { +SkData* SkImage::encode(SkEncodedImageFormat type, int quality) const { SkBitmap bm; // TODO: Right now, the encoders don't handle F16 or linearly premultiplied data. Once they do, // we should decode in "color space aware" mode, then re-encode that. For now, work around this // by asking for a legacy decode (which gives us the raw data in N32). if (as_IB(this)->getROPixels(&bm, SkDestinationSurfaceColorMode::kLegacy)) { - return SkImageEncoder::EncodeData(bm, type, quality); + SkDynamicMemoryWStream buf; + return SkEncodeImage(&buf, bm, type, quality) ? buf.detachAsData().release() : nullptr; } return nullptr; } SkData* SkImage::encode(SkPixelSerializer* serializer) const { - sk_sp<SkPixelSerializer> defaultSerializer; - SkPixelSerializer* effectiveSerializer = serializer; - if (!effectiveSerializer) { - defaultSerializer.reset(SkImageEncoder::CreatePixelSerializer()); - SkASSERT(defaultSerializer.get()); - effectiveSerializer = defaultSerializer.get(); - } sk_sp<SkData> encoded(this->refEncoded()); - if (encoded && effectiveSerializer->useEncodedData(encoded->data(), encoded->size())) { + if (encoded && + (!serializer || serializer->useEncodedData(encoded->data(), encoded->size()))) { return encoded.release(); } @@ -134,7 +129,13 @@ SkData* SkImage::encode(SkPixelSerializer* serializer) const { // by asking for a legacy decode (which gives us the raw data in N32). if (as_IB(this)->getROPixels(&bm, SkDestinationSurfaceColorMode::kLegacy) && bm.requestLock(&apu)) { - return effectiveSerializer->encode(apu.pixmap()); + if (serializer) { + return serializer->encode(apu.pixmap()); + } else { + SkDynamicMemoryWStream buf; + return SkEncodeImage(&buf, apu.pixmap(), SkEncodedImageFormat::kPNG, 100) + ? buf.detachAsData().release() : nullptr; + } } return nullptr; @@ -188,7 +189,7 @@ GrBackendObject SkImage::getTextureHandle(bool flushPendingGrContextIO) const { GrTexture* texture = as_IB(this)->peekTexture(); if (texture) { GrContext* context = texture->getContext(); - if (context) { + if (context) { if (flushPendingGrContextIO) { context->prepareSurfaceForExternalIO(texture); } diff --git a/src/images/SkForceLinking.cpp b/src/images/SkForceLinking.cpp index 81d485c882..dfed6b4b57 100644 --- a/src/images/SkForceLinking.cpp +++ b/src/images/SkForceLinking.cpp @@ -5,7 +5,7 @@ * found in the LICENSE file. */ -#include "SkImageEncoder.h" +#include "SkImageEncoderPriv.h" #include "SkForceLinking.h" // This method is required to fool the linker into not discarding the pre-main @@ -30,10 +30,10 @@ int SkForceLinking(bool doNotPassTrue) { #endif #if defined (SK_USE_CG_ENCODER) - CreateImageEncoder_CG(SkImageEncoder::kPNG_Type); + CreateImageEncoder_CG(SkEncodedImageFormat::kPNG); #endif #if defined (SK_USE_WIC_ENCODER) - CreateImageEncoder_WIC(SkImageEncoder::kPNG_Type); + CreateImageEncoder_WIC(SkEncodedImageFormat::kPNG); #endif return -1; } diff --git a/src/images/SkImageEncoder.cpp b/src/images/SkImageEncoder.cpp index 787ff8ef62..c137bc5e0a 100644 --- a/src/images/SkImageEncoder.cpp +++ b/src/images/SkImageEncoder.cpp @@ -5,84 +5,15 @@ * found in the LICENSE file. */ -#include "SkImageEncoder.h" -#include "SkBitmap.h" -#include "SkPixelSerializer.h" -#include "SkPixmap.h" -#include "SkStream.h" -#include "SkTemplates.h" +#include "SkImageEncoderPriv.h" -SkImageEncoder::~SkImageEncoder() {} - -bool SkImageEncoder::encodeStream(SkWStream* stream, const SkBitmap& bm, - int quality) { - quality = SkMin32(100, SkMax32(0, quality)); - return this->onEncode(stream, bm, quality); -} - -bool SkImageEncoder::encodeFile(const char file[], const SkBitmap& bm, - int quality) { - quality = SkMin32(100, SkMax32(0, quality)); - SkFILEWStream stream(file); - return this->onEncode(&stream, bm, quality); -} - -SkData* SkImageEncoder::encodeData(const SkBitmap& bm, int quality) { - SkDynamicMemoryWStream stream; - quality = SkMin32(100, SkMax32(0, quality)); - if (this->onEncode(&stream, bm, quality)) { - return stream.detachAsData().release(); - } - return nullptr; -} - -bool SkImageEncoder::EncodeFile(const char file[], const SkBitmap& bm, Type t, - int quality) { - std::unique_ptr<SkImageEncoder> enc(SkImageEncoder::Create(t)); - return enc.get() && enc.get()->encodeFile(file, bm, quality); -} - -bool SkImageEncoder::EncodeStream(SkWStream* stream, const SkBitmap& bm, Type t, - int quality) { - std::unique_ptr<SkImageEncoder> enc(SkImageEncoder::Create(t)); - return enc.get() && enc.get()->encodeStream(stream, bm, quality); -} - -SkData* SkImageEncoder::EncodeData(const SkBitmap& bm, Type t, int quality) { - std::unique_ptr<SkImageEncoder> enc(SkImageEncoder::Create(t)); - return enc.get() ? enc.get()->encodeData(bm, quality) : nullptr; -} - -SkData* SkImageEncoder::EncodeData(const SkImageInfo& info, const void* pixels, size_t rowBytes, - Type t, int quality) { +bool SkEncodeImage(SkWStream* dst, const SkPixmap& src, + SkEncodedImageFormat format, int quality) { SkBitmap bm; - if (!bm.installPixels(info, const_cast<void*>(pixels), rowBytes)) { - return nullptr; + if (!bm.installPixels(src)) { + return false; } bm.setImmutable(); - return SkImageEncoder::EncodeData(bm, t, quality); -} - -SkData* SkImageEncoder::EncodeData(const SkPixmap& pixmap, - Type t, int quality) { - SkBitmap bm; - if (!bm.installPixels(pixmap)) { - 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; + std::unique_ptr<SkImageEncoder> enc(SkImageEncoder::Create((SkImageEncoder::Type)format)); + return enc && enc->encodeStream(dst, bm, quality); } diff --git a/src/images/SkImageEncoderPriv.h b/src/images/SkImageEncoderPriv.h new file mode 100644 index 0000000000..9b632f5a5b --- /dev/null +++ b/src/images/SkImageEncoderPriv.h @@ -0,0 +1,68 @@ +/* + * Copyright 2016 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkImageEncoderPriv_DEFINED +#define SkImageEncoderPriv_DEFINED + +#include "SkImageEncoder.h" +#include "SkTRegistry.h" + +#ifndef SK_SUPPORT_LEGACY_IMAGE_ENCODER_CLASS + + // TODO(halcanary): replace this class and registry system with something simpler. + class SkImageEncoder { + public: + typedef SkEncodedImageFormat Type; + static SkImageEncoder* Create(SkEncodedImageFormat); + + virtual ~SkImageEncoder() {} + + bool encodeStream(SkWStream* dst, const SkBitmap& src, int quality) { + return this->onEncode(dst, src, SkMin32(100, SkMax32(0, quality))); + } + + protected: + /** + * Encode bitmap 'bm' in the desired format, writing results to + * stream 'stream', at quality level 'quality' (which can be in + * range 0-100). + */ + virtual bool onEncode(SkWStream* stream, const SkBitmap& bm, int quality) = 0; + }; + +#endif // SK_SUPPORT_LEGACY_IMAGE_ENCODER_CLASS + +// This macro declares a global (i.e., non-class owned) creation entry point +// for each encoder (e.g., CreateJPEGImageEncoder) +#define DECLARE_ENCODER_CREATOR(codec) \ + SK_API SkImageEncoder *Create ## codec (); + +// This macro defines the global creation entry point for each encoder. Each +// encoder implementation that registers with the encoder factory must call it. +#define DEFINE_ENCODER_CREATOR(codec) \ + SkImageEncoder* Create##codec() { return new Sk##codec; } + +// All the encoders known by Skia. Note that, depending on the compiler settings, +// not all of these will be available +DECLARE_ENCODER_CREATOR(JPEGImageEncoder); +DECLARE_ENCODER_CREATOR(PNGImageEncoder); +DECLARE_ENCODER_CREATOR(KTXImageEncoder); +DECLARE_ENCODER_CREATOR(WEBPImageEncoder); + +#if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) +SkImageEncoder* CreateImageEncoder_CG(SkImageEncoder::Type type); +#endif + +#if defined(SK_BUILD_FOR_WIN) +SkImageEncoder* CreateImageEncoder_WIC(SkImageEncoder::Type type); +#endif + +// Typedef to make registering encoder callback easier +// This has to be defined outside SkImageEncoder. :( +typedef SkTRegistry<SkImageEncoder*(*)(SkImageEncoder::Type)> SkImageEncoder_EncodeReg; + +#endif // SkImageEncoderPriv_DEFINED diff --git a/src/images/SkImageEncoder_Factory.cpp b/src/images/SkImageEncoder_Factory.cpp index 887ce55dda..a5ae8d0560 100644 --- a/src/images/SkImageEncoder_Factory.cpp +++ b/src/images/SkImageEncoder_Factory.cpp @@ -5,11 +5,11 @@ * found in the LICENSE file. */ -#include "SkImageEncoder.h" +#include "SkImageEncoderPriv.h" template SkImageEncoder_EncodeReg* SkImageEncoder_EncodeReg::gHead; -SkImageEncoder* SkImageEncoder::Create(Type t) { +SkImageEncoder* SkImageEncoder::Create(SkImageEncoder::Type t) { SkImageEncoder* codec = nullptr; const SkImageEncoder_EncodeReg* curr = SkImageEncoder_EncodeReg::Head(); while (curr) { diff --git a/src/images/SkJPEGImageEncoder.cpp b/src/images/SkJPEGImageEncoder.cpp index 66b2440c20..97b8bbc30d 100644 --- a/src/images/SkJPEGImageEncoder.cpp +++ b/src/images/SkJPEGImageEncoder.cpp @@ -5,20 +5,20 @@ * found in the LICENSE file. */ +#include "SkImageEncoderPriv.h" -#include "SkImageEncoder.h" +#include "SkCanvas.h" #include "SkColorPriv.h" #include "SkDither.h" +#include "SkJPEGWriteUtility.h" +#include "SkRect.h" #include "SkStream.h" #include "SkTemplates.h" #include "SkTime.h" #include "SkUtils.h" -#include "SkRect.h" -#include "SkCanvas.h" - #include <stdio.h> -#include "SkJPEGWriteUtility.h" + extern "C" { #include "jpeglib.h" #include "jerror.h" @@ -178,7 +178,7 @@ DEFINE_ENCODER_CREATOR(JPEGImageEncoder); /////////////////////////////////////////////////////////////////////////////// static SkImageEncoder* sk_libjpeg_efactory(SkImageEncoder::Type t) { - return (SkImageEncoder::kJPEG_Type == t) ? new SkJPEGImageEncoder : nullptr; + return (SkEncodedImageFormat::kJPEG == (SkEncodedImageFormat)t) ? new SkJPEGImageEncoder : nullptr; } static SkImageEncoder_EncodeReg gEReg(sk_libjpeg_efactory); diff --git a/src/images/SkKTXImageEncoder.cpp b/src/images/SkKTXImageEncoder.cpp index 62c0346c3e..6717bea5f7 100644 --- a/src/images/SkKTXImageEncoder.cpp +++ b/src/images/SkKTXImageEncoder.cpp @@ -6,7 +6,7 @@ */ #include "SkColorPriv.h" -#include "SkImageEncoder.h" +#include "SkImageEncoderPriv.h" #include "SkImageGenerator.h" #include "SkPixelRef.h" #include "SkStream.h" @@ -40,7 +40,7 @@ protected: DEFINE_ENCODER_CREATOR(KTXImageEncoder); SkImageEncoder* sk_libktx_efactory(SkImageEncoder::Type t) { - return (SkImageEncoder::kKTX_Type == t) ? new SkKTXImageEncoder : nullptr; + return (SkEncodedImageFormat::kKTX == (SkEncodedImageFormat)t) ? new SkKTXImageEncoder : nullptr; } static SkImageEncoder_EncodeReg gEReg(sk_libktx_efactory); diff --git a/src/images/SkPNGImageEncoder.cpp b/src/images/SkPNGImageEncoder.cpp index 69a53fb2a4..4fc3a10272 100644 --- a/src/images/SkPNGImageEncoder.cpp +++ b/src/images/SkPNGImageEncoder.cpp @@ -5,7 +5,7 @@ * found in the LICENSE file. */ -#include "SkImageEncoder.h" +#include "SkImageEncoderPriv.h" #include "SkColor.h" #include "SkColorPriv.h" #include "SkDither.h" @@ -356,7 +356,7 @@ DEFINE_ENCODER_CREATOR(PNGImageEncoder); /////////////////////////////////////////////////////////////////////////////// SkImageEncoder* sk_libpng_efactory(SkImageEncoder::Type t) { - return (SkImageEncoder::kPNG_Type == t) ? new SkPNGImageEncoder : nullptr; + return (SkEncodedImageFormat::kPNG == (SkEncodedImageFormat)t) ? new SkPNGImageEncoder : nullptr; } static SkImageEncoder_EncodeReg gEReg(sk_libpng_efactory); diff --git a/src/images/SkWEBPImageEncoder.cpp b/src/images/SkWEBPImageEncoder.cpp index 116608a253..27c984ac1b 100644 --- a/src/images/SkWEBPImageEncoder.cpp +++ b/src/images/SkWEBPImageEncoder.cpp @@ -15,7 +15,7 @@ */ #include "SkBitmap.h" -#include "SkImageEncoder.h" +#include "SkImageEncoderPriv.h" #include "SkColorPriv.h" #include "SkStream.h" #include "SkTemplates.h" @@ -241,7 +241,7 @@ DEFINE_ENCODER_CREATOR(WEBPImageEncoder); /////////////////////////////////////////////////////////////////////////////// static SkImageEncoder* sk_libwebp_efactory(SkImageEncoder::Type t) { - return (SkImageEncoder::kWEBP_Type == t) ? new SkWEBPImageEncoder : nullptr; + return (SkEncodedImageFormat::kWEBP == (SkEncodedImageFormat)t) ? new SkWEBPImageEncoder : nullptr; } static SkImageEncoder_EncodeReg gEReg(sk_libwebp_efactory); diff --git a/src/ports/SkImageEncoder_CG.cpp b/src/ports/SkImageEncoder_CG.cpp index 789285626c..0c3d22d0f6 100644 --- a/src/ports/SkImageEncoder_CG.cpp +++ b/src/ports/SkImageEncoder_CG.cpp @@ -12,7 +12,7 @@ #include "SkCGUtils.h" #include "SkColorPriv.h" #include "SkData.h" -#include "SkImageEncoder.h" +#include "SkImageEncoderPriv.h" #include "SkStream.h" #include "SkStreamPriv.h" #include "SkTemplates.h" @@ -59,13 +59,13 @@ static CGImageDestinationRef SkStreamToImageDestination(SkWStream* stream, class SkImageEncoder_CG : public SkImageEncoder { public: - SkImageEncoder_CG(Type t) : fType(t) {} + SkImageEncoder_CG(SkEncodedImageFormat t) : fType(t) {} protected: virtual bool onEncode(SkWStream* stream, const SkBitmap& bm, int quality); private: - Type fType; + SkEncodedImageFormat fType; }; /* Encode bitmaps via CGImageDestination. We setup a DataConsumer which writes @@ -80,19 +80,19 @@ bool SkImageEncoder_CG::onEncode(SkWStream* stream, const SkBitmap& bm, CFStringRef type; switch (fType) { - case kICO_Type: + case SkEncodedImageFormat::kICO: type = kUTTypeICO; break; - case kBMP_Type: + case SkEncodedImageFormat::kBMP: type = kUTTypeBMP; break; - case kGIF_Type: + case SkEncodedImageFormat::kGIF: type = kUTTypeGIF; break; - case kJPEG_Type: + case SkEncodedImageFormat::kJPEG: type = kUTTypeJPEG; break; - case kPNG_Type: + case SkEncodedImageFormat::kPNG: // PNG encoding an ARGB_4444 bitmap gives the following errors in GM: // <Error>: CGImageDestinationAddImage image could not be converted to destination // format. @@ -127,13 +127,13 @@ bool SkImageEncoder_CG::onEncode(SkWStream* stream, const SkBitmap& bm, /////////////////////////////////////////////////////////////////////////////// #ifdef SK_USE_CG_ENCODER -static SkImageEncoder* sk_imageencoder_cg_factory(SkImageEncoder::Type t) { +static SkImageEncoder* sk_imageencoder_cg_factory(SkEncodedImageFormat t) { switch (t) { - case SkImageEncoder::kICO_Type: - case SkImageEncoder::kBMP_Type: - case SkImageEncoder::kGIF_Type: - case SkImageEncoder::kJPEG_Type: - case SkImageEncoder::kPNG_Type: + case SkEncodedImageFormat::kICO: + case SkEncodedImageFormat::kBMP: + case SkEncodedImageFormat::kGIF: + case SkEncodedImageFormat::kJPEG: + case SkEncodedImageFormat::kPNG: break; default: return nullptr; @@ -145,7 +145,7 @@ static SkImageEncoder_EncodeReg gEReg(sk_imageencoder_cg_factory); #endif SkImageEncoder* CreateImageEncoder_CG(SkImageEncoder::Type type) { - return new SkImageEncoder_CG(type); + return new SkImageEncoder_CG((SkEncodedImageFormat)type); } #endif//defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) diff --git a/src/ports/SkImageEncoder_WIC.cpp b/src/ports/SkImageEncoder_WIC.cpp index 6524526bdb..035359e792 100644 --- a/src/ports/SkImageEncoder_WIC.cpp +++ b/src/ports/SkImageEncoder_WIC.cpp @@ -31,7 +31,7 @@ #include <wincodec.h> #include "SkAutoCoInitialize.h" #include "SkBitmap.h" -#include "SkImageEncoder.h" +#include "SkImageEncoderPriv.h" #include "SkIStream.h" #include "SkStream.h" #include "SkTScopedComPtr.h" @@ -48,13 +48,13 @@ class SkImageEncoder_WIC : public SkImageEncoder { public: - SkImageEncoder_WIC(Type t) : fType(t) {} + SkImageEncoder_WIC(SkEncodedImageFormat t) : fType(t) {} protected: virtual bool onEncode(SkWStream* stream, const SkBitmap& bm, int quality); private: - Type fType; + SkEncodedImageFormat fType; }; bool SkImageEncoder_WIC::onEncode(SkWStream* stream @@ -63,10 +63,10 @@ bool SkImageEncoder_WIC::onEncode(SkWStream* stream { GUID type; switch (fType) { - case kJPEG_Type: + case SkEncodedImageFormat::kJPEG: type = GUID_ContainerFormatJpeg; break; - case kPNG_Type: + case SkEncodedImageFormat::kPNG: type = GUID_ContainerFormatPng; break; default: @@ -97,7 +97,7 @@ bool SkImageEncoder_WIC::onEncode(SkWStream* stream size_t rowBytes = bitmap.rowBytes(); SkAutoMalloc pixelStorage; WICPixelFormatGUID formatDesired = GUID_WICPixelFormat32bppBGRA; - if (kJPEG_Type == fType) { + if (SkEncodedImageFormat::kJPEG == fType) { formatDesired = GUID_WICPixelFormat24bppBGR; rowBytes = SkAlign4(bitmap.width() * 3); pixelStorage.reset(rowBytes * bitmap.height()); @@ -219,10 +219,10 @@ bool SkImageEncoder_WIC::onEncode(SkWStream* stream /////////////////////////////////////////////////////////////////////////////// #ifdef SK_USE_WIC_ENCODER -static SkImageEncoder* sk_imageencoder_wic_factory(SkImageEncoder::Type t) { +static SkImageEncoder* sk_imageencoder_wic_factory(SkEncodedImageFormat t) { switch (t) { - case SkImageEncoder::kPNG_Type: - case SkImageEncoder::kJPEG_Type: + case SkEncodedImageFormat::kPNG: + case SkEncodedImageFormat::kJPEG: break; default: return nullptr; @@ -234,7 +234,7 @@ static SkImageEncoder_EncodeReg gEReg(sk_imageencoder_wic_factory); #endif SkImageEncoder* CreateImageEncoder_WIC(SkImageEncoder::Type type) { - return new SkImageEncoder_WIC(type); + return new SkImageEncoder_WIC((SkEncodedImageFormat)type); } #endif // defined(SK_BUILD_FOR_WIN32) diff --git a/src/ports/SkImageEncoder_none.cpp b/src/ports/SkImageEncoder_none.cpp index 327a220111..a26698beeb 100644 --- a/src/ports/SkImageEncoder_none.cpp +++ b/src/ports/SkImageEncoder_none.cpp @@ -5,63 +5,9 @@ * found in the LICENSE file. */ -#include "SkBitmap.h" -#include "SkImage.h" #include "SkImageEncoder.h" -#include "SkPixelSerializer.h" -#include "SkStream.h" -///////////////////////////////////////////////////////////////////////// - -// Empty implementations for SkImageEncoder. - -SkImageEncoder* SkImageEncoder::Create(Type t) { - return nullptr; -} - -bool SkImageEncoder::EncodeFile(const char file[], const SkBitmap&, Type, int quality) { - return false; -} - -bool SkImageEncoder::EncodeStream(SkWStream*, const SkBitmap&, SkImageEncoder::Type, int) { - return false; -} - -SkData* SkImageEncoder::EncodeData(const SkBitmap&, Type, int quality) { - return nullptr; -} - -SkData* SkImageEncoder::EncodeData(const SkImageInfo&, const void* pixels, size_t rowBytes, - Type, int quality) { - return nullptr; -} - -SkData* SkImageEncoder::EncodeData(const SkPixmap&, Type, int) { - return nullptr; -} - -bool SkImageEncoder::encodeStream(SkWStream*, const SkBitmap&, int) { - return false; -} - -SkData* SkImageEncoder::encodeData(const SkBitmap&, int) { - return nullptr; -} - -bool SkImageEncoder::encodeFile(const char file[], const SkBitmap& bm, int quality) { +bool SkEncodeImage(SkWStream*, const SkPixmap&, SkEncodedImageFormat, int) { return false; } -namespace { -class ImageEncoderPixelSerializer final : public SkPixelSerializer { -protected: - bool onUseEncodedData(const void*, size_t) override { return true; } - SkData* onEncode(const SkPixmap&) override { return nullptr; } -}; -} // namespace - -SkPixelSerializer* SkImageEncoder::CreatePixelSerializer() { - return new ImageEncoderPixelSerializer; -} - -///////////////////////////////////////////////////////////////////////// diff --git a/src/svg/SkSVGDevice.cpp b/src/svg/SkSVGDevice.cpp index ffdf034ab1..b9f1424e6e 100644 --- a/src/svg/SkSVGDevice.cpp +++ b/src/svg/SkSVGDevice.cpp @@ -659,10 +659,14 @@ void SkSVGDevice::drawPath(const SkDraw& draw, const SkPath& path, const SkPaint } } +static sk_sp<SkData> encode(const SkBitmap& src) { + SkDynamicMemoryWStream buf; + return SkEncodeImage(&buf, src, SkEncodedImageFormat::kPNG, 80) ? buf.detachAsData() : nullptr; +} + void SkSVGDevice::drawBitmapCommon(const SkDraw& draw, const SkBitmap& bm, const SkPaint& paint) { - sk_sp<const SkData> pngData( - SkImageEncoder::EncodeData(bm, SkImageEncoder::kPNG_Type, SkImageEncoder::kDefaultQuality)); + sk_sp<SkData> pngData = encode(bm); if (!pngData) { return; } diff --git a/src/xps/SkXPSDevice.cpp b/src/xps/SkXPSDevice.cpp index 22c7b248d1..37874337e0 100644 --- a/src/xps/SkXPSDevice.cpp +++ b/src/xps/SkXPSDevice.cpp @@ -658,8 +658,7 @@ HRESULT SkXPSDevice::createXpsImageBrush( const SkAlpha alpha, IXpsOMTileBrush** xpsBrush) { SkDynamicMemoryWStream write; - if (!SkImageEncoder::EncodeStream(&write, bitmap, - SkImageEncoder::kPNG_Type, 100)) { + if (!SkEncodeImage(&write, bitmap, SkEncodedImageFormat::kPNG, 100)) { HRM(E_FAIL, "Unable to encode bitmap as png."); } SkMemoryStream* read = new SkMemoryStream; diff --git a/tests/BlitRowTest.cpp b/tests/BlitRowTest.cpp index b4a4a64dfe..3439a5e09d 100644 --- a/tests/BlitRowTest.cpp +++ b/tests/BlitRowTest.cpp @@ -12,6 +12,8 @@ #include "SkRect.h" #include "Test.h" +#include "sk_tool_utils.h" + // these are in the same order as the SkColorType enum static const char* gColorTypeName[] = { "None", "A8", "565", "4444", "RGBA", "BGRA", "Index8" @@ -178,7 +180,7 @@ struct Mesh { #include "SkImageEncoder.h" static void save_bm(const SkBitmap& bm, const char name[]) { - SkImageEncoder::EncodeFile(name, bm, SkImageEncoder::kPNG_Type, 100); + sk_tool_utils::EncodeImageToFile(name, bm, SkEncodedImageFormat::kPNG, 100); } static bool gOnce; diff --git a/tests/CodecTest.cpp b/tests/CodecTest.cpp index dacabca3fd..d15c710325 100644 --- a/tests/CodecTest.cpp +++ b/tests/CodecTest.cpp @@ -23,6 +23,8 @@ #include "png.h" +#include "sk_tool_utils.h" + #if PNG_LIBPNG_VER_MAJOR == 1 && PNG_LIBPNG_VER_MINOR < 5 // FIXME (scroggo): Google3 needs to be updated to use a newer version of libpng. In // the meantime, we had to break some pieces of SkPngCodec in order to support Google3. @@ -1102,7 +1104,7 @@ static void check_round_trip(skiatest::Reporter* r, SkCodec* origCodec, const Sk // Encode the image to png. sk_sp<SkData> data = - sk_sp<SkData>(SkImageEncoder::EncodeData(bm1, SkImageEncoder::kPNG_Type, 100)); + sk_sp<SkData>(sk_tool_utils::EncodeImageToData(bm1, SkEncodedImageFormat::kPNG, 100)); std::unique_ptr<SkCodec> codec(SkCodec::NewFromData(data)); REPORTER_ASSERT(r, color_type_match(info.colorType(), codec->getInfo().colorType())); diff --git a/tests/ImageTest.cpp b/tests/ImageTest.cpp index 18883feded..020e322f91 100644 --- a/tests/ImageTest.cpp +++ b/tests/ImageTest.cpp @@ -26,6 +26,8 @@ #include "SkUtils.h" #include "Test.h" +#include "sk_tool_utils.h" + #if SK_SUPPORT_GPU #include "GrGpu.h" #endif @@ -153,7 +155,7 @@ static sk_sp<SkImage> create_codec_image() { sk_sp<SkData> data(create_image_data(&info)); SkBitmap bitmap; bitmap.installPixels(info, data->writable_data(), info.minRowBytes()); - sk_sp<SkData> src(SkImageEncoder::EncodeData(bitmap, SkImageEncoder::kPNG_Type, 100)); + sk_sp<SkData> src(sk_tool_utils::EncodeImageToData(bitmap, SkEncodedImageFormat::kPNG, 100)); return SkImage::MakeFromEncoded(std::move(src)); } #if SK_SUPPORT_GPU @@ -1026,7 +1028,7 @@ DEF_TEST(image_roundtrip_encode, reporter) { make_all_premul(&bm0); auto img0 = SkImage::MakeFromBitmap(bm0); - sk_sp<SkData> data(img0->encode(SkImageEncoder::kPNG_Type, 100)); + sk_sp<SkData> data(img0->encode(SkEncodedImageFormat::kPNG, 100)); auto img1 = SkImage::MakeFromEncoded(data); SkBitmap bm1; diff --git a/tests/PDFDocumentTest.cpp b/tests/PDFDocumentTest.cpp index fca8496f26..b3200156c6 100644 --- a/tests/PDFDocumentTest.cpp +++ b/tests/PDFDocumentTest.cpp @@ -14,6 +14,8 @@ #include "SkStream.h" #include "SkPixelSerializer.h" +#include "sk_tool_utils.h" + static void test_empty(skiatest::Reporter* reporter) { SkDynamicMemoryWStream stream; @@ -119,14 +121,7 @@ namespace { class JPEGSerializer final : public SkPixelSerializer { bool onUseEncodedData(const void*, size_t) override { return true; } SkData* onEncode(const SkPixmap& pixmap) override { - SkBitmap bm; - return bm.installPixels(pixmap.info(), - pixmap.writable_addr(), - pixmap.rowBytes(), - pixmap.ctable(), - nullptr, nullptr) - ? SkImageEncoder::EncodeData(bm, SkImageEncoder::kJPEG_Type, 85) - : nullptr; + return sk_tool_utils::EncodeImageToData(pixmap, SkEncodedImageFormat::kJPEG, 85).release(); } }; } // namespace diff --git a/tests/PathOpsConicIntersectionTest.cpp b/tests/PathOpsConicIntersectionTest.cpp index 41c0acb9fd..1de1583a7b 100644 --- a/tests/PathOpsConicIntersectionTest.cpp +++ b/tests/PathOpsConicIntersectionTest.cpp @@ -110,8 +110,8 @@ static void writePng(const SkConic& c, const SkConic ch[2], const char* name) { canvas.drawPath(path, paint); SkString filename("c:\\Users\\caryclark\\Documents\\"); filename.appendf("%s.png", name); - SkImageEncoder::EncodeFile(filename.c_str(), bitmap, - SkImageEncoder::kPNG_Type, 100); + sk_tool_utils::EncodeImageToFile(filename.c_str(), bitmap, + SkEncodedImageFormat::kPNG, 100); } static void writeDPng(const SkDConic& dC, const char* name) { @@ -152,8 +152,8 @@ static void writeDPng(const SkDConic& dC, const char* name) { canvas.drawPath(path, paint); SkString filename("c:\\Users\\caryclark\\Documents\\"); filename.appendf("%s.png", name); - SkImageEncoder::EncodeFile(filename.c_str(), bitmap, - SkImageEncoder::kPNG_Type, 100); + sk_tool_utils::EncodeImageToFile(filename.c_str(), bitmap, + SkEncodedImageFormat::kPNG, 100); } #endif @@ -290,7 +290,7 @@ static void writeFrames() { } SkString filename("c:\\Users\\caryclark\\Documents\\"); filename.appendf("f%d.png", index); - SkImageEncoder::EncodeFile(filename.c_str(), bitmap, SkImageEncoder::kPNG_Type, 100); + sk_tool_utils::EncodeImageToFile(filename.c_str(), bitmap, SkEncodedImageFormat::kPNG, 100); } } #endif diff --git a/tests/PathOpsSkpClipTest.cpp b/tests/PathOpsSkpClipTest.cpp index 3cbe7efdba..57e9bd1b64 100644 --- a/tests/PathOpsSkpClipTest.cpp +++ b/tests/PathOpsSkpClipTest.cpp @@ -429,7 +429,7 @@ static void drawPict(SkPicture* pic, SkCanvas* canvas, int scale) { static void writePict(const SkBitmap& bitmap, const char* outDir, const char* pngName) { SkString outFile = get_sum_path(outDir); outFile.appendf("%s%s", PATH_SLASH, pngName); - if (!SkImageEncoder::EncodeFile(outFile.c_str(), bitmap, SkImageEncoder::kPNG_Type, 100)) { + if (!sk_tool_utils::EncodeImageToFile(outFile.c_str(), bitmap, SkEncodedImageFormat::kPNG, 100)) { SkDebugf("unable to encode gr %s (width=%d height=%d)\n", pngName, bitmap.width(), bitmap.height()); } diff --git a/tests/SkpSkGrTest.cpp b/tests/SkpSkGrTest.cpp index c87926ecf8..0e425a006a 100644 --- a/tests/SkpSkGrTest.cpp +++ b/tests/SkpSkGrTest.cpp @@ -368,8 +368,8 @@ static void drawPict(SkPicture* pic, SkCanvas* canvas, int scale) { static void writePict(const SkBitmap& bitmap, const char* outDir, const char* pngName) { SkString outFile = make_filepath(0, outDir, pngName); - if (!SkImageEncoder::EncodeFile(outFile.c_str(), bitmap, - SkImageEncoder::kPNG_Type, 100)) { + if (!sk_tool_utils::EncodeImageToFile(outFile.c_str(), bitmap, + SkEncodedImageFormat::kPNG, 100)) { SkDebugf("unable to encode gr %s (width=%d height=%d)br \n", pngName, bitmap.width(), bitmap.height()); } diff --git a/tools/colorspaceinfo.cpp b/tools/colorspaceinfo.cpp index 301f47dc5a..945c4a5fca 100644 --- a/tools/colorspaceinfo.cpp +++ b/tools/colorspaceinfo.cpp @@ -17,6 +17,8 @@ #include "SkMatrix44.h" #include "SkOSFile.h" +#include "sk_tool_utils.h" + __SK_FORCE_IMAGE_DECODER_LINKING; DEFINE_string(input, "input.png", "A path to the input image or icc profile."); @@ -219,7 +221,7 @@ int main(int argc, char** argv) { } // Finally, encode the result to the output file. - sk_sp<SkData> out(SkImageEncoder::EncodeData(gamut, SkImageEncoder::kPNG_Type, 100)); + sk_sp<SkData> out = sk_tool_utils::EncodeImageToData(gamut, SkEncodedImageFormat::kPNG, 100); if (!out) { SkDebugf("Failed to encode gamut output.\n"); return -1; @@ -243,7 +245,7 @@ int main(int argc, char** argv) { SkDebugf("Could not decode input image.\n"); return -1; } - out.reset(SkImageEncoder::EncodeData(bitmap, SkImageEncoder::kPNG_Type, 100)); + out = sk_tool_utils::EncodeImageToData(bitmap, SkEncodedImageFormat::kPNG, 100); if (!out) { SkDebugf("Failed to encode uncorrected image.\n"); return -1; diff --git a/tools/get_images_from_skps.cpp b/tools/get_images_from_skps.cpp index 6cd35122ad..d3a2343b88 100644 --- a/tools/get_images_from_skps.cpp +++ b/tools/get_images_from_skps.cpp @@ -65,14 +65,14 @@ struct Sniffer : public SkPixelSerializer { } SkString ext; switch (codec->getEncodedFormat()) { - case SkEncodedFormat::kBMP_SkEncodedFormat: ext = "bmp"; break; - case SkEncodedFormat::kGIF_SkEncodedFormat: ext = "gif"; break; - case SkEncodedFormat::kICO_SkEncodedFormat: ext = "ico"; break; - case SkEncodedFormat::kJPEG_SkEncodedFormat: ext = "jpg"; break; - case SkEncodedFormat::kPNG_SkEncodedFormat: ext = "png"; break; - case SkEncodedFormat::kDNG_SkEncodedFormat: ext = "dng"; break; - case SkEncodedFormat::kWBMP_SkEncodedFormat: ext = "wbmp"; break; - case SkEncodedFormat::kWEBP_SkEncodedFormat: ext = "webp"; break; + case SkEncodedImageFormat::kBMP: ext = "bmp"; break; + case SkEncodedImageFormat::kGIF: ext = "gif"; break; + case SkEncodedImageFormat::kICO: ext = "ico"; break; + case SkEncodedImageFormat::kJPEG: ext = "jpg"; break; + case SkEncodedImageFormat::kPNG: ext = "png"; break; + case SkEncodedImageFormat::kDNG: ext = "dng"; break; + case SkEncodedImageFormat::kWBMP: ext = "wbmp"; break; + case SkEncodedImageFormat::kWEBP: ext = "webp"; break; default: // This should be unreachable because we cannot create a codec if we do not know // the image type. diff --git a/tools/imgblur.cpp b/tools/imgblur.cpp index 3a0ae00f3b..28d8447ef0 100644 --- a/tools/imgblur.cpp +++ b/tools/imgblur.cpp @@ -66,7 +66,7 @@ int tool_main(int argc, char** argv) { SkBitmap dst = sk_tool_utils::slow_blur(src, (float) FLAGS_sigma); - if (!SkImageEncoder::EncodeFile(FLAGS_out[0], dst, SkImageEncoder::kPNG_Type, 100)) { + if (!sk_tool_utils::EncodeImageToFile(FLAGS_out[0], dst, SkEncodedImageFormat::kPNG, 100)) { if (!FLAGS_quiet) { SkDebugf("Couldn't write to file: %s\n", FLAGS_out[0]); } diff --git a/tools/picture_utils.cpp b/tools/picture_utils.cpp index 43ca2f07bf..84925b4dad 100644 --- a/tools/picture_utils.cpp +++ b/tools/picture_utils.cpp @@ -17,6 +17,8 @@ #include "SkStream.h" #include "SkString.h" +#include "sk_tool_utils.h" + namespace sk_tools { void force_all_opaque(const SkBitmap& bitmap) { SkASSERT(kN32_SkColorType == bitmap.colorType()); @@ -63,7 +65,7 @@ namespace sk_tools { partialPath.set(dirPath); } SkString fullPath = SkOSPath::Join(partialPath.c_str(), baseName.c_str()); - if (SkImageEncoder::EncodeFile(fullPath.c_str(), bm, SkImageEncoder::kPNG_Type, 100)) { + if (sk_tool_utils::EncodeImageToFile(fullPath.c_str(), bm, SkEncodedImageFormat::kPNG, 100)) { return true; } else { SkDebugf("Failed to write the bitmap to %s.\n", fullPath.c_str()); diff --git a/tools/sk_tool_utils.h b/tools/sk_tool_utils.h index c6abbcf7c2..526f0ef505 100644 --- a/tools/sk_tool_utils.h +++ b/tools/sk_tool_utils.h @@ -225,6 +225,31 @@ namespace sk_tool_utils { SkTDArray<TopoTestNode*> fDependencies; }; + template <typename T> + inline bool EncodeImageToFile(const char* path, const T& src, SkEncodedImageFormat f, int q) { + SkFILEWStream file(path); + return file.isValid() && SkEncodeImage(&file, src, f, q); + } + + template <typename T> + inline sk_sp<SkData> EncodeImageToData(const T& src, SkEncodedImageFormat f, int q) { + SkDynamicMemoryWStream buf; + return SkEncodeImage(&buf, src , f, q) ? buf.detachAsData() : nullptr; + } + + /** + * Uses SkEncodeImage to serialize images that are not already + * encoded as SkEncodedImageFormat::kPNG images. + */ + inline sk_sp<SkPixelSerializer> MakePixelSerializer() { + struct EncodeImagePixelSerializer final : SkPixelSerializer { + bool onUseEncodedData(const void*, size_t) override { return true; } + SkData* onEncode(const SkPixmap& pmap) override { + return EncodeImageToData(pmap, SkEncodedImageFormat::kPNG, 100).release(); + } + }; + return sk_make_sp<EncodeImagePixelSerializer>(); + } } // namespace sk_tool_utils #endif // sk_tool_utils_DEFINED diff --git a/tools/skdiff/skdiff_utils.cpp b/tools/skdiff/skdiff_utils.cpp index f788ec8cef..f8eed908b7 100644 --- a/tools/skdiff/skdiff_utils.cpp +++ b/tools/skdiff/skdiff_utils.cpp @@ -6,6 +6,7 @@ */ #include "skdiff.h" #include "skdiff_utils.h" +#include "sk_tool_utils.h" #include "SkBitmap.h" #include "SkCodec.h" #include "SkData.h" @@ -82,8 +83,8 @@ bool write_bitmap(const SkString& path, const SkBitmap& bitmap) { SkBitmap copy; bitmap.copyTo(©, kN32_SkColorType); force_all_opaque(copy); - return SkImageEncoder::EncodeFile(path.c_str(), copy, - SkImageEncoder::kPNG_Type, 100); + return sk_tool_utils::EncodeImageToFile(path.c_str(), copy, + SkEncodedImageFormat::kPNG, 100); } /// Return a copy of the "input" string, within which we have replaced all instances diff --git a/tools/skiaserve/Request.cpp b/tools/skiaserve/Request.cpp index c1b3b25cdd..2064a464f0 100644 --- a/tools/skiaserve/Request.cpp +++ b/tools/skiaserve/Request.cpp @@ -11,6 +11,7 @@ #include "SkPixelSerializer.h" #include "SkPM4fPriv.h" #include "picture_utils.h" +#include "sk_tool_utils.h" using namespace sk_gpu_test; @@ -117,7 +118,7 @@ sk_sp<SkData> Request::writeOutSkp() { SkDynamicMemoryWStream outStream; - sk_sp<SkPixelSerializer> serializer(SkImageEncoder::CreatePixelSerializer()); + sk_sp<SkPixelSerializer> serializer = sk_tool_utils::MakePixelSerializer(); picture->serialize(&outStream, serializer.get()); return outStream.detachAsData(); |