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.h" 9 10 #include "Resources.h" 11 #include "SkCanvas.h" 12 #include "SkCodec.h" 13 #include "SkData.h" 14 #include "SkImage.h" 15 #include "SkImageEncoderPriv.h" 16 #include "SkJpegEncoder.h" 17 #include "SkPngEncoder.h" 18 #include "SkWebpEncoder.h" 19 20 namespace skiagm { 21 22 static const int imageWidth = 128; 23 static const int imageHeight = 128; 24 25 static void make(SkBitmap* bitmap, SkColorType colorType, SkAlphaType alphaType, 26 sk_sp<SkColorSpace> colorSpace) { 27 const char* resource; 28 switch (colorType) { 29 case kGray_8_SkColorType: 30 resource = "images/grayscale.jpg"; 31 alphaType = kOpaque_SkAlphaType; 32 break; 33 case kRGB_565_SkColorType: 34 resource = "images/color_wheel.jpg"; 35 alphaType = kOpaque_SkAlphaType; 36 break; 37 default: 38 resource = (kOpaque_SkAlphaType == alphaType) ? "images/color_wheel.jpg" 39 : "images/color_wheel.png"; 40 break; 41 } 42 43 sk_sp<SkData> data = GetResourceAsData(resource); 44 if (!data) { 45 return; 46 } 47 std::unique_ptr<SkCodec> codec = SkCodec::MakeFromData(data); 48 SkImageInfo dstInfo = codec->getInfo().makeColorType(colorType) 49 .makeAlphaType(alphaType) 50 .makeColorSpace(colorSpace); 51 bitmap->allocPixels(dstInfo); 52 codec->getPixels(dstInfo, bitmap->getPixels(), bitmap->rowBytes()); 53 } 54 55 static sk_sp<SkData> encode_data(const SkBitmap& bitmap, SkEncodedImageFormat format) { 56 SkPixmap src; 57 if (!bitmap.peekPixels(&src)) { 58 return nullptr; 59 } 60 SkDynamicMemoryWStream buf; 61 62 switch (format) { 63 case SkEncodedImageFormat::kPNG: 64 SkAssertResult(SkPngEncoder::Encode(&buf, src, SkPngEncoder::Options())); 65 break; 66 case SkEncodedImageFormat::kWEBP: 67 SkAssertResult(SkWebpEncoder::Encode(&buf, src, SkWebpEncoder::Options())); 68 break; 69 case SkEncodedImageFormat::kJPEG: 70 SkAssertResult(SkJpegEncoder::Encode(&buf, src, SkJpegEncoder::Options())); 71 break; 72 default: 73 break; 74 } 75 return buf.detachAsData(); 76 } 77 78 class EncodeSRGBGM : public GM { 79 public: 80 EncodeSRGBGM(SkEncodedImageFormat format) 81 : fEncodedFormat(format) 82 {} 83 84 protected: 85 SkString onShortName() override { 86 const char* format = nullptr; 87 switch (fEncodedFormat) { 88 case SkEncodedImageFormat::kPNG: 89 format = "png"; 90 break; 91 case SkEncodedImageFormat::kWEBP: 92 format = "webp"; 93 break; 94 case SkEncodedImageFormat::kJPEG: 95 format = "jpg"; 96 break; 97 default: 98 break; 99 } 100 return SkStringPrintf("encode-srgb-%s", format); 101 } 102 103 SkISize onISize() override { 104 return SkISize::Make(imageWidth * 2, imageHeight * 15); 105 } 106 107 void onDraw(SkCanvas* canvas) override { 108 const SkColorType colorTypes[] = { 109 kN32_SkColorType, kRGBA_F16_SkColorType, kGray_8_SkColorType, kRGB_565_SkColorType, 110 }; 111 const SkAlphaType alphaTypes[] = { 112 kUnpremul_SkAlphaType, kPremul_SkAlphaType, kOpaque_SkAlphaType, 113 }; 114 const sk_sp<SkColorSpace> colorSpaces[] = { 115 nullptr, SkColorSpace::MakeSRGB(), 116 }; 117 118 SkBitmap bitmap; 119 for (SkColorType colorType : colorTypes) { 120 for (SkAlphaType alphaType : alphaTypes) { 121 canvas->save(); 122 for (sk_sp<SkColorSpace> colorSpace : colorSpaces) { 123 make(&bitmap, colorType, alphaType, colorSpace); 124 auto image = SkImage::MakeFromEncoded(encode_data(bitmap, fEncodedFormat)); 125 canvas->drawImage(image.get(), 0.0f, 0.0f); 126 canvas->translate((float) imageWidth, 0.0f); 127 } 128 canvas->restore(); 129 canvas->translate(0.0f, (float) imageHeight); 130 } 131 } 132 } 133 134 private: 135 SkEncodedImageFormat fEncodedFormat; 136 137 typedef GM INHERITED; 138 }; 139 140 DEF_GM( return new EncodeSRGBGM(SkEncodedImageFormat::kPNG); ) 141 DEF_GM( return new EncodeSRGBGM(SkEncodedImageFormat::kWEBP); ) 142 DEF_GM( return new EncodeSRGBGM(SkEncodedImageFormat::kJPEG); ) 143 } 144