1 /* 2 * Copyright 2017 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 "SkColorSpacePriv.h" 9 #include "SkImage.h" 10 #include "SkPngEncoder.h" 11 12 #include "Resources.h" 13 14 /** 15 * Create a color space that swaps the red, green, and blue channels. 16 */ 17 static sk_sp<SkColorSpace> gbr_color_space() { 18 float gbr[9]; 19 gbr[0] = gSRGB_toXYZD50[1]; 20 gbr[1] = gSRGB_toXYZD50[2]; 21 gbr[2] = gSRGB_toXYZD50[0]; 22 gbr[3] = gSRGB_toXYZD50[4]; 23 gbr[4] = gSRGB_toXYZD50[5]; 24 gbr[5] = gSRGB_toXYZD50[3]; 25 gbr[6] = gSRGB_toXYZD50[7]; 26 gbr[7] = gSRGB_toXYZD50[8]; 27 gbr[8] = gSRGB_toXYZD50[6]; 28 SkMatrix44 toXYZD50(SkMatrix44::kUninitialized_Constructor); 29 toXYZD50.set3x3RowMajorf(gbr); 30 return SkColorSpace::MakeRGB(SkColorSpace::kSRGB_RenderTargetGamma, toXYZD50); 31 } 32 33 /** 34 * Create a color space with a steep transfer function. 35 */ 36 static sk_sp<SkColorSpace> tf_color_space() { 37 SkColorSpaceTransferFn fn; 38 fn.fA = 1.f; fn.fB = 0.f; fn.fC = 0.f; fn.fD = 0.f; fn.fE = 0.f; fn.fF = 0.f; fn.fG = 50.f; 39 return SkColorSpace::MakeRGB(fn, SkColorSpace::kSRGB_Gamut); 40 } 41 42 /** 43 * Create a wide gamut color space. 44 */ 45 static sk_sp<SkColorSpace> wide_gamut_color_space() { 46 return SkColorSpace::MakeRGB(SkColorSpace::kSRGB_RenderTargetGamma, 47 SkColorSpace::kRec2020_Gamut); 48 } 49 50 int main(int argc, char** argv) { 51 sk_sp<SkImage> image = GetResourceAsImage("flutter_logo.jpg"); 52 if (!image) { 53 SkDebugf("Cannot find flutter_logo.jpg in resources.\n"); 54 return 1; 55 } 56 57 // Encode an image with a gbr color space. 58 SkImageInfo info = SkImageInfo::MakeN32(image->width(), image->height(), kOpaque_SkAlphaType, 59 gbr_color_space()); 60 size_t rowBytes = info.minRowBytes(); 61 SkAutoTMalloc<uint8_t> storage(rowBytes * image->height()); 62 SkPixmap src(info, storage.get(), rowBytes); 63 image->readPixels(src, 0, 0, SkImage::kDisallow_CachingHint); 64 SkFILEWStream dst0("gbr.png"); 65 SkPngEncoder::Options opts; 66 opts.fUnpremulBehavior = SkTransferFunctionBehavior::kIgnore; // Does not matter for opaque src 67 SkAssertResult(SkPngEncoder::Encode(&dst0, src, opts)); 68 69 // Encode an image with steep transfer function. 70 src.setColorSpace(tf_color_space()); 71 image->readPixels(src, 0, 0, SkImage::kDisallow_CachingHint); 72 SkFILEWStream dst1("tf.png"); 73 SkAssertResult(SkPngEncoder::Encode(&dst1, src, opts)); 74 75 // Encode a wide gamut image. 76 src.setColorSpace(wide_gamut_color_space()); 77 image->readPixels(src, 0, 0, SkImage::kDisallow_CachingHint); 78 SkFILEWStream dst2("wide-gamut.png"); 79 SkAssertResult(SkPngEncoder::Encode(&dst2, src, opts)); 80 81 return 0; 82 } 83