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