150 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			150 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			C++
		
	
	
	
| /*
 | |
|  * 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<SkData> 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:
 | |
|     using INHERITED = GM;
 | |
| };
 | |
| 
 | |
| DEF_GM( return new EncodePlatformGM; )
 | |
| }  // namespace skiagm
 |