/* * Copyright 2016 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "gm/gm.h" #include "include/core/SkBitmap.h" #include "include/core/SkCanvas.h" #include "include/core/SkData.h" #include "include/core/SkEncodedImageFormat.h" #include "include/core/SkImage.h" #include "include/core/SkImageInfo.h" #include "include/core/SkPixmap.h" #include "include/core/SkRect.h" #include "include/core/SkRefCnt.h" #include "include/core/SkSize.h" #include "include/core/SkStream.h" #include "include/core/SkString.h" #include "include/core/SkTypes.h" #include "include/encode/SkJpegEncoder.h" #include "include/encode/SkPngEncoder.h" #include "include/encode/SkWebpEncoder.h" #include "tools/Resources.h" #if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) || defined(SK_BUILD_FOR_WIN) \ || defined(SK_ENABLE_NDK_IMAGES) #include "src/images/SkImageEncoderPriv.h" #endif namespace { static const struct { SkEncodedImageFormat format; int quality; } gRecs[] = { #if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) { SkEncodedImageFormat::kPNG, 100}, { SkEncodedImageFormat::kJPEG, 100}, { SkEncodedImageFormat::kGIF, 100}, { SkEncodedImageFormat::kBMP, 100}, { SkEncodedImageFormat::kICO, 100}, #elif defined(SK_BUILD_FOR_WIN) // Our WIC encoder does not support GIF, BMP, or ICO. { SkEncodedImageFormat::kPNG, 100}, { SkEncodedImageFormat::kJPEG, 100}, { SkEncodedImageFormat::kPNG, 100}, { SkEncodedImageFormat::kPNG, 100}, { SkEncodedImageFormat::kPNG, 100}, #else // We don't support GIF, BMP, or ICO. This applies to both NDK and SkEncoder. { SkEncodedImageFormat::kPNG, 100}, { SkEncodedImageFormat::kJPEG, 100}, { SkEncodedImageFormat::kWEBP, 100}, // Lossless { SkEncodedImageFormat::kWEBP, 80}, // Lossy { SkEncodedImageFormat::kPNG, 100}, #endif }; } // anonymous namespace static sk_sp encode_data(SkEncodedImageFormat type, const SkBitmap& bitmap, int quality) { SkPixmap src; if (!bitmap.peekPixels(&src)) { return nullptr; } SkDynamicMemoryWStream buf; #if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) return SkEncodeImageWithCG(&buf, src, type) ? buf.detachAsData() : nullptr; #elif defined(SK_BUILD_FOR_WIN) return SkEncodeImageWithWIC(&buf, src, type, quality) ? buf.detachAsData() : nullptr; #elif defined(SK_ENABLE_NDK_IMAGES) return SkEncodeImageWithNDK(&buf, src, type, quality) ? buf.detachAsData() : nullptr; #else switch (type) { case SkEncodedImageFormat::kPNG: { bool success = SkPngEncoder::Encode(&buf, src, SkPngEncoder::Options()); return success ? buf.detachAsData() : nullptr; } case SkEncodedImageFormat::kJPEG: { bool success = SkJpegEncoder::Encode(&buf, src, SkJpegEncoder::Options()); return success ? buf.detachAsData() : nullptr; } case SkEncodedImageFormat::kWEBP: { bool success = SkWebpEncoder::Encode(&buf, src, SkWebpEncoder::Options()); return success ? buf.detachAsData() : nullptr; } default: SkUNREACHABLE; } #endif } namespace skiagm { class EncodePlatformGM : public GM { public: EncodePlatformGM() {} protected: SkString onShortName() override { return SkString("encode-platform"); } SkISize onISize() override { return SkISize::Make(256 * SK_ARRAY_COUNT(gRecs), 256 * 3); } DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override { SkBitmap opaqueBm, premulBm, unpremulBm; if (!GetResourceAsBitmap("images/mandrill_256.png", &opaqueBm)) { *errorMsg = "Could not load images/mandrill_256.png.png. " "Did you forget to set the resourcePath?"; return DrawResult::kFail; } SkBitmap tmp; if (!GetResourceAsBitmap("images/yellow_rose.png", &tmp)) { *errorMsg = "Could not load images/yellow_rose.png. " "Did you forget to set the resourcePath?"; return DrawResult::kFail; } tmp.extractSubset(&premulBm, SkIRect::MakeWH(256, 256)); tmp.reset(); unpremulBm.allocPixels(premulBm.info().makeAlphaType(kUnpremul_SkAlphaType)); SkAssertResult(premulBm.readPixels(unpremulBm.pixmap())); for (const auto& rec : gRecs) { auto fmt = rec.format; int q = rec.quality; auto opaqueImage = SkImage::MakeFromEncoded(encode_data(fmt, opaqueBm, q)); auto premulImage = SkImage::MakeFromEncoded(encode_data(fmt, premulBm, q)); auto unpremulImage = SkImage::MakeFromEncoded(encode_data(fmt, unpremulBm, q)); canvas->drawImage(opaqueImage.get(), 0.0f, 0.0f); canvas->drawImage(premulImage.get(), 0.0f, 256.0f); canvas->drawImage(unpremulImage.get(), 0.0f, 512.0f); canvas->translate(256.0f, 0.0f); } return DrawResult::kOk; } private: typedef GM INHERITED; }; DEF_GM( return new EncodePlatformGM; ) } // namespace skiagm