1/* 2 * Copyright 2016 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8#include "gm/gm.h" 9#include "include/core/SkBitmap.h" 10#include "include/core/SkCanvas.h" 11#include "include/core/SkData.h" 12#include "include/core/SkEncodedImageFormat.h" 13#include "include/core/SkImage.h" 14#include "include/core/SkImageInfo.h" 15#include "include/core/SkPixmap.h" 16#include "include/core/SkRect.h" 17#include "include/core/SkRefCnt.h" 18#include "include/core/SkSize.h" 19#include "include/core/SkStream.h" 20#include "include/core/SkString.h" 21#include "include/core/SkTypes.h" 22#include "include/encode/SkJpegEncoder.h" 23#include "include/encode/SkPngEncoder.h" 24#include "include/encode/SkWebpEncoder.h" 25#include "tools/Resources.h" 26 27#if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) || defined(SK_BUILD_FOR_WIN) \ 28 || defined(SK_ENABLE_NDK_IMAGES) 29#include "src/images/SkImageEncoderPriv.h" 30#endif 31 32namespace { 33 34static const struct { 35 SkEncodedImageFormat format; 36 int quality; 37} gRecs[] = { 38#if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) 39 { SkEncodedImageFormat::kPNG, 100}, 40 { SkEncodedImageFormat::kJPEG, 100}, 41 { SkEncodedImageFormat::kGIF, 100}, 42 { SkEncodedImageFormat::kBMP, 100}, 43 { SkEncodedImageFormat::kICO, 100}, 44#elif defined(SK_BUILD_FOR_WIN) 45 // Our WIC encoder does not support GIF, BMP, or ICO. 46 { SkEncodedImageFormat::kPNG, 100}, 47 { SkEncodedImageFormat::kJPEG, 100}, 48 { SkEncodedImageFormat::kPNG, 100}, 49 { SkEncodedImageFormat::kPNG, 100}, 50 { SkEncodedImageFormat::kPNG, 100}, 51#else 52 // We don't support GIF, BMP, or ICO. This applies to both NDK and SkEncoder. 53 { SkEncodedImageFormat::kPNG, 100}, 54 { SkEncodedImageFormat::kJPEG, 100}, 55 { SkEncodedImageFormat::kWEBP, 100}, // Lossless 56 { SkEncodedImageFormat::kWEBP, 80}, // Lossy 57 { SkEncodedImageFormat::kPNG, 100}, 58#endif 59}; 60 61} // anonymous namespace 62 63static sk_sp<SkData> encode_data(SkEncodedImageFormat type, const SkBitmap& bitmap, int quality) { 64 SkPixmap src; 65 if (!bitmap.peekPixels(&src)) { 66 return nullptr; 67 } 68 SkDynamicMemoryWStream buf; 69 #if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) 70 return SkEncodeImageWithCG(&buf, src, type) ? buf.detachAsData() : nullptr; 71 #elif defined(SK_BUILD_FOR_WIN) 72 return SkEncodeImageWithWIC(&buf, src, type, quality) ? buf.detachAsData() : nullptr; 73 #elif defined(SK_ENABLE_NDK_IMAGES) 74 return SkEncodeImageWithNDK(&buf, src, type, quality) ? buf.detachAsData() : nullptr; 75 #else 76 switch (type) { 77 case SkEncodedImageFormat::kPNG: { 78 bool success = SkPngEncoder::Encode(&buf, src, SkPngEncoder::Options()); 79 return success ? buf.detachAsData() : nullptr; 80 } 81 case SkEncodedImageFormat::kJPEG: { 82 bool success = SkJpegEncoder::Encode(&buf, src, SkJpegEncoder::Options()); 83 return success ? buf.detachAsData() : nullptr; 84 } 85 case SkEncodedImageFormat::kWEBP: { 86 bool success = SkWebpEncoder::Encode(&buf, src, SkWebpEncoder::Options()); 87 return success ? buf.detachAsData() : nullptr; 88 } 89 default: 90 SkUNREACHABLE; 91 } 92 #endif 93} 94 95namespace skiagm { 96 97class EncodePlatformGM : public GM { 98public: 99 EncodePlatformGM() {} 100 101protected: 102 SkString onShortName() override { 103 return SkString("encode-platform"); 104 } 105 106 SkISize onISize() override { 107 return SkISize::Make(256 * SK_ARRAY_COUNT(gRecs), 256 * 3); 108 } 109 110 DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override { 111 SkBitmap opaqueBm, premulBm, unpremulBm; 112 113 if (!GetResourceAsBitmap("images/mandrill_256.png", &opaqueBm)) { 114 *errorMsg = "Could not load images/mandrill_256.png.png. " 115 "Did you forget to set the resourcePath?"; 116 return DrawResult::kFail; 117 } 118 SkBitmap tmp; 119 if (!GetResourceAsBitmap("images/yellow_rose.png", &tmp)) { 120 *errorMsg = "Could not load images/yellow_rose.png. " 121 "Did you forget to set the resourcePath?"; 122 return DrawResult::kFail; 123 } 124 tmp.extractSubset(&premulBm, SkIRect::MakeWH(256, 256)); 125 tmp.reset(); 126 unpremulBm.allocPixels(premulBm.info().makeAlphaType(kUnpremul_SkAlphaType)); 127 SkAssertResult(premulBm.readPixels(unpremulBm.pixmap())); 128 129 for (const auto& rec : gRecs) { 130 auto fmt = rec.format; int q = rec.quality; 131 auto opaqueImage = SkImage::MakeFromEncoded(encode_data(fmt, opaqueBm, q)); 132 auto premulImage = SkImage::MakeFromEncoded(encode_data(fmt, premulBm, q)); 133 auto unpremulImage = SkImage::MakeFromEncoded(encode_data(fmt, unpremulBm, q)); 134 135 canvas->drawImage(opaqueImage.get(), 0.0f, 0.0f); 136 canvas->drawImage(premulImage.get(), 0.0f, 256.0f); 137 canvas->drawImage(unpremulImage.get(), 0.0f, 512.0f); 138 139 canvas->translate(256.0f, 0.0f); 140 } 141 return DrawResult::kOk; 142 } 143 144private: 145 using INHERITED = GM; 146}; 147 148DEF_GM( return new EncodePlatformGM; ) 149} // namespace skiagm 150