Flutter Engine
The Flutter Engine
imgcvt.cpp
Go to the documentation of this file.
1/*
2* Copyright 2018 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
14#include "modules/skcms/skcms.h"
16
17static void write_png(const char* path, sk_sp<SkImage> img) {
18 sk_sp<SkData> png = SkPngEncoder::Encode(nullptr, img.get(), {});
19 SkASSERT(png);
20 SkFILEWStream(path).write(png->data(), png->size());
21}
22
23int main(int argc, char** argv) {
24 const char* source_path = argc > 1 ? argv[1] : nullptr;
25 if (!source_path) {
26 SkDebugf("Please pass an image or profile to convert"
27 " as the first argument to this program.\n");
28 return 1;
29 }
30
31 const char* dst_profile_path = argc > 2 ? argv[2] : nullptr;
32 skcms_ICCProfile dst_profile = *skcms_sRGB_profile();
33 sk_sp<SkData> dst_blob;
34 if (dst_profile_path) {
35 dst_blob = SkData::MakeFromFileName(dst_profile_path);
36 if (!skcms_Parse(dst_blob->data(), dst_blob->size(), &dst_profile)) {
37 SkDebugf("Can't parse %s as an ICC profile.\n", dst_profile_path);
38 return 1;
39 }
40 }
41
42 auto blob = SkData::MakeFromFileName(source_path);
43
44 skcms_ICCProfile src_profile;
45 if (skcms_Parse(blob->data(), blob->size(), &src_profile)) {
46 // Transform white, black, primaries, and primary complements.
47 float src[] = {
48 0,0,0,
49 1,1,1,
50
51 1,0,0,
52 0,1,0,
53 0,0,1,
54
55 0,1,1,
56 1,0,1,
57 1,1,0,
58 };
59 float dst[24] = {0};
60
61 if (!skcms_Transform(
64 8)) {
65 SkDebugf("Cannot transform.\n");
66 return 1;
67 }
68 for (int i = 0; i < 8; i++) {
69 SkDebugf("(%g, %g, %g) --> (%+.4f, %+.4f, %+.4f)\n",
70 src[3*i+0], src[3*i+1], src[3*i+2],
71 dst[3*i+0], dst[3*i+1], dst[3*i+2]);
72 }
73 return 0;
74 }
75
77 if (!image) {
78 SkDebugf("Couldn't decode %s as an SkImage or an ICC profile.\n", source_path);
79 return 1;
80 }
81
83 if (!image) {
84 SkDebugf("Converting to raster image failed.\n");
85 return 1;
86 }
87
88 SkPixmap pixmap;
89 if (!image->peekPixels(&pixmap)) {
90 SkDebugf("We really should be able to peek raster pixels.\n");
91 return 1;
92 }
93
94 sk_sp<SkColorSpace> dst_cs = SkColorSpace::Make(dst_profile);
95 if (!dst_cs) {
96 SkDebugf("We can't convert to this destination profile as-is. Coercing it.\n");
98 dst_cs = SkColorSpace::Make(dst_profile);
99 }
100 if (!dst_cs) {
101 SkDebugf("We can't convert to this destination profile at all.\n");
102 return 1;
103 }
104 }
105
106 { // transform with skcms
109 src_cs->toProfile(&src_profile);
110
112 switch (pixmap.colorType()) {
115 default:
116 SkDebugf("color type %d not yet supported, imgcvt.cpp needs an update.\n",
117 pixmap.colorType());
118 return 1;
119 }
120
121 if (pixmap.alphaType() == kUnpremul_SkAlphaType) {
122 SkDebugf("not premul, that's weird.\n");
123 return 1;
124 }
126
127 if (pixmap.rowBytes() != (size_t)pixmap.width() * pixmap.info().bytesPerPixel()) {
128 SkDebugf("not a tight pixmap, need a loop here\n");
129 return 1;
130 }
131
132 if (!skcms_Transform(pixmap.addr(), fmt,alpha, &src_profile,
133 pixmap.writable_addr(), fmt,alpha, &dst_profile,
134 pixmap.width() * pixmap.height())) {
135 SkDebugf("skcms_Transform() failed\n");
136 return 1;
137 }
138 pixmap.setColorSpace(dst_cs);
139
140 write_png("transformed-skcms.png", SkImages::RasterFromPixmapCopy(pixmap));
141 }
142
143 { // transform with writePixels()
145 if (!surface) {
146 SkDebugf("couldn't create a surface\n");
147 return 1;
148 }
149
150 surface->writePixels(pixmap, 0,0);
151
152 write_png("transformed-writepixels.png", surface->makeImageSnapshot());
153 }
154
155 { // transform by drawing
157 if (!surface) {
158 SkDebugf("couldn't create a surface\n");
159 return 1;
160 }
161
162 surface->getCanvas()->drawImage(image, 0,0);
163
164 write_png("transformed-draw.png", surface->makeImageSnapshot());
165 }
166
167 return 0;
168}
kUnpremul_SkAlphaType
#define SkASSERT(cond)
Definition: SkAssert.h:116
SkColorSpace * sk_srgb_singleton()
@ kBGRA_8888_SkColorType
pixel with 8 bits for blue, green, red, alpha; in 32-bit word
Definition: SkColorType.h:26
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition: SkColorType.h:24
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
void toProfile(skcms_ICCProfile *) const
static sk_sp< SkColorSpace > Make(const skcms_ICCProfile &)
const void * data() const
Definition: SkData.h:37
static sk_sp< SkData > MakeFromFileName(const char path[])
Definition: SkData.cpp:148
size_t size() const
Definition: SkData.h:30
bool write(const void *buffer, size_t size) override
Definition: SkStream.cpp:426
sk_sp< SkImage > makeRasterImage(GrDirectContext *, CachingHint cachingHint=kDisallow_CachingHint) const
Definition: SkImage.cpp:267
SkColorSpace * colorSpace() const
Definition: SkImage.cpp:156
bool peekPixels(SkPixmap *pixmap) const
Definition: SkImage.cpp:34
size_t rowBytes() const
Definition: SkPixmap.h:145
int width() const
Definition: SkPixmap.h:160
SkColorType colorType() const
Definition: SkPixmap.h:173
void setColorSpace(sk_sp< SkColorSpace > colorSpace)
Definition: SkPixmap.cpp:57
const SkImageInfo & info() const
Definition: SkPixmap.h:135
void * writable_addr() const
Definition: SkPixmap.h:483
const void * addr() const
Definition: SkPixmap.h:153
int height() const
Definition: SkPixmap.h:166
SkAlphaType alphaType() const
Definition: SkPixmap.h:175
T * get() const
Definition: SkRefCnt.h:303
VkSurfaceKHR surface
Definition: main.cc:49
int main(int argc, char **argv)
Definition: imgcvt.cpp:23
static void write_png(const char *path, sk_sp< SkImage > img)
Definition: imgcvt.cpp:17
char ** argv
Definition: library.h:9
SK_API sk_sp< SkImage > DeferredFromEncodedData(sk_sp< SkData > encoded, std::optional< SkAlphaType > alphaType=std::nullopt)
SK_API sk_sp< SkImage > RasterFromPixmapCopy(const SkPixmap &pixmap)
SK_API bool Encode(SkWStream *dst, const SkPixmap &src, const Options &options)
sk_sp< const SkImage > image
Definition: SkRecords.h:269
SK_API sk_sp< SkSurface > Raster(const SkImageInfo &imageInfo, size_t rowBytes, const SkSurfaceProps *surfaceProps)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57
dst
Definition: cp.py:12
static SkString fmt(SkColor4f c)
Definition: p3.cpp:43
bool skcms_Transform(const void *src, skcms_PixelFormat srcFmt, skcms_AlphaFormat srcAlpha, const skcms_ICCProfile *srcProfile, void *dst, skcms_PixelFormat dstFmt, skcms_AlphaFormat dstAlpha, const skcms_ICCProfile *dstProfile, size_t nz)
Definition: skcms.cc:2495
bool skcms_MakeUsableAsDestinationWithSingleCurve(skcms_ICCProfile *profile)
Definition: skcms.cc:2854
const skcms_ICCProfile * skcms_sRGB_profile()
Definition: skcms.cc:1393
skcms_PixelFormat
Definition: skcms_public.h:273
@ skcms_PixelFormat_BGRA_8888
Definition: skcms_public.h:288
@ skcms_PixelFormat_RGB_fff
Definition: skcms_public.h:315
@ skcms_PixelFormat_RGBA_8888
Definition: skcms_public.h:287
static bool skcms_Parse(const void *buf, size_t len, skcms_ICCProfile *profile)
Definition: skcms_public.h:245
@ skcms_AlphaFormat_Unpremul
Definition: skcms_public.h:339
@ skcms_AlphaFormat_PremulAsEncoded
Definition: skcms_public.h:341
int bytesPerPixel() const
Definition: SkImageInfo.h:492
SkImageInfo makeColorSpace(sk_sp< SkColorSpace > cs) const