| /* |
| * 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.h" |
| |
| #include "Resources.h" |
| #include "SkCanvas.h" |
| #include "SkCodec.h" |
| #include "SkColorSpace_Base.h" |
| #include "SkData.h" |
| #include "SkImage.h" |
| #include "SkImageEncoderPriv.h" |
| #include "SkJpegEncoder.h" |
| #include "SkPngEncoder.h" |
| #include "SkPM4f.h" |
| #include "SkSRGB.h" |
| #include "SkWebpEncoder.h" |
| |
| namespace skiagm { |
| |
| static const int imageWidth = 128; |
| static const int imageHeight = 128; |
| |
| sk_sp<SkColorSpace> fix_for_colortype(sk_sp<SkColorSpace> colorSpace, SkColorType colorType) { |
| if (kRGBA_F16_SkColorType == colorType) { |
| if (!colorSpace) { |
| return SkColorSpace::MakeSRGBLinear(); |
| } |
| |
| return as_CSB(colorSpace)->makeLinearGamma(); |
| } |
| |
| return colorSpace; |
| } |
| |
| static void make(SkBitmap* bitmap, SkColorType colorType, SkAlphaType alphaType, |
| sk_sp<SkColorSpace> colorSpace) { |
| const char* resource; |
| switch (colorType) { |
| case kGray_8_SkColorType: |
| resource = "grayscale.jpg"; |
| alphaType = kOpaque_SkAlphaType; |
| break; |
| case kRGB_565_SkColorType: |
| resource = "color_wheel.jpg"; |
| alphaType = kOpaque_SkAlphaType; |
| break; |
| default: |
| resource = (kOpaque_SkAlphaType == alphaType) ? "color_wheel.jpg" |
| : "color_wheel.png"; |
| break; |
| } |
| |
| sk_sp<SkData> data = GetResourceAsData(resource); |
| std::unique_ptr<SkCodec> codec = SkCodec::MakeFromData(data); |
| SkImageInfo dstInfo = codec->getInfo().makeColorType(colorType) |
| .makeAlphaType(alphaType) |
| .makeColorSpace(fix_for_colortype(colorSpace, colorType)); |
| bitmap->allocPixels(dstInfo); |
| codec->getPixels(dstInfo, bitmap->getPixels(), bitmap->rowBytes()); |
| } |
| |
| static sk_sp<SkData> encode_data(const SkBitmap& bitmap, SkEncodedImageFormat format) { |
| SkPixmap src; |
| if (!bitmap.peekPixels(&src)) { |
| return nullptr; |
| } |
| SkDynamicMemoryWStream buf; |
| |
| SkPngEncoder::Options pngOptions; |
| SkWebpEncoder::Options webpOptions; |
| SkTransferFunctionBehavior behavior = bitmap.colorSpace() |
| ? SkTransferFunctionBehavior::kRespect : SkTransferFunctionBehavior::kIgnore; |
| pngOptions.fUnpremulBehavior = behavior; |
| webpOptions.fUnpremulBehavior = behavior; |
| |
| switch (format) { |
| case SkEncodedImageFormat::kPNG: |
| SkAssertResult(SkPngEncoder::Encode(&buf, src, pngOptions)); |
| break; |
| case SkEncodedImageFormat::kWEBP: |
| SkAssertResult(SkWebpEncoder::Encode(&buf, src, webpOptions)); |
| break; |
| case SkEncodedImageFormat::kJPEG: |
| SkAssertResult(SkJpegEncoder::Encode(&buf, src, SkJpegEncoder::Options())); |
| break; |
| default: |
| break; |
| } |
| return buf.detachAsData(); |
| } |
| |
| class EncodeSRGBGM : public GM { |
| public: |
| EncodeSRGBGM(SkEncodedImageFormat format) |
| : fEncodedFormat(format) |
| {} |
| |
| protected: |
| SkString onShortName() override { |
| const char* format = nullptr; |
| switch (fEncodedFormat) { |
| case SkEncodedImageFormat::kPNG: |
| format = "png"; |
| break; |
| case SkEncodedImageFormat::kWEBP: |
| format = "webp"; |
| break; |
| case SkEncodedImageFormat::kJPEG: |
| format = "jpg"; |
| break; |
| default: |
| break; |
| } |
| return SkStringPrintf("encode-srgb-%s", format); |
| } |
| |
| SkISize onISize() override { |
| return SkISize::Make(imageWidth * 2, imageHeight * 15); |
| } |
| |
| void onDraw(SkCanvas* canvas) override { |
| const SkColorType colorTypes[] = { |
| kN32_SkColorType, kRGBA_F16_SkColorType, kGray_8_SkColorType, kRGB_565_SkColorType, |
| }; |
| const SkAlphaType alphaTypes[] = { |
| kUnpremul_SkAlphaType, kPremul_SkAlphaType, kOpaque_SkAlphaType, |
| }; |
| const sk_sp<SkColorSpace> colorSpaces[] = { |
| nullptr, SkColorSpace::MakeSRGB(), |
| }; |
| |
| SkBitmap bitmap; |
| for (SkColorType colorType : colorTypes) { |
| for (SkAlphaType alphaType : alphaTypes) { |
| canvas->save(); |
| for (sk_sp<SkColorSpace> colorSpace : colorSpaces) { |
| make(&bitmap, colorType, alphaType, colorSpace); |
| auto image = SkImage::MakeFromEncoded(encode_data(bitmap, fEncodedFormat)); |
| canvas->drawImage(image.get(), 0.0f, 0.0f); |
| canvas->translate((float) imageWidth, 0.0f); |
| } |
| canvas->restore(); |
| canvas->translate(0.0f, (float) imageHeight); |
| } |
| } |
| } |
| |
| private: |
| SkEncodedImageFormat fEncodedFormat; |
| |
| typedef GM INHERITED; |
| }; |
| |
| DEF_GM( return new EncodeSRGBGM(SkEncodedImageFormat::kPNG); ) |
| DEF_GM( return new EncodeSRGBGM(SkEncodedImageFormat::kWEBP); ) |
| DEF_GM( return new EncodeSRGBGM(SkEncodedImageFormat::kJPEG); ) |
| } |