Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Functions
AndroidCodecTest.cpp File Reference
#include "include/codec/SkAndroidCodec.h"
#include "include/codec/SkCodec.h"
#include "include/codec/SkEncodedImageFormat.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkData.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/core/SkTypes.h"
#include "include/private/SkGainmapInfo.h"
#include "modules/skcms/skcms.h"
#include "tests/Test.h"
#include "tools/Resources.h"
#include <cstdint>
#include <cstring>
#include <initializer_list>
#include <memory>
#include <utility>

Go to the source code of this file.

Functions

static SkISize times (const SkISize &size, float factor)
 
static SkISize plus (const SkISize &size, int term)
 
static bool invalid (const SkISize &size)
 
 DEF_TEST (AndroidCodec_computeSampleSize, r)
 
 DEF_TEST (AndroidCodec_wide, r)
 
 DEF_TEST (AndroidCodec_P3, r)
 
 DEF_TEST (AndroidCodec_HLG, r)
 
 DEF_TEST (AndroidCodec_PQ, r)
 

Function Documentation

◆ DEF_TEST() [1/5]

DEF_TEST ( AndroidCodec_computeSampleSize  ,
 
)

Definition at line 41 of file AndroidCodecTest.cpp.

41 {
42 if (GetResourcePath().isEmpty()) {
43 return;
44 }
45 for (const char* file : { "images/color_wheel.webp",
46 "images/ship.png",
47 "images/dog.jpg",
48 "images/color_wheel.gif",
49 "images/rle.bmp",
50 "images/google_chrome.ico",
51 "images/mandrill.wbmp",
52#ifdef SK_CODEC_DECODES_RAW
53 "images/sample_1mp.dng",
54#endif
55 }) {
56 auto data = GetResourceAsData(file);
57 if (!data) {
58 ERRORF(r, "Could not get %s", file);
59 continue;
60 }
61
62 auto codec = SkAndroidCodec::MakeFromCodec(SkCodec::MakeFromData(std::move(data)));
63 if (!codec) {
64 ERRORF(r, "Could not create codec for %s", file);
65 continue;
66 }
67
68 const auto dims = codec->getInfo().dimensions();
69 const SkISize downscales[] = {
70 plus(dims, -1),
71 times(dims, .15f),
72 times(dims, .6f),
73 { (int32_t) (dims.width() * .25f), (int32_t) (dims.height() * .75f ) },
74 { 1, 1 },
75 { 1, 2 },
76 { 2, 1 },
77 { 0, -1 },
78 { dims.width(), dims.height() - 1 },
79 };
80 for (SkISize size : downscales) {
81 const auto requested = size;
82 const int computedSampleSize = codec->computeSampleSize(&size);
83 REPORTER_ASSERT(r, size.width() >= 1 && size.height() >= 1);
84 if (codec->getEncodedFormat() == SkEncodedImageFormat::kWEBP) {
85 // WebP supports arbitrary down-scaling.
86 REPORTER_ASSERT(r, size == requested || invalid(requested));
87 } else if (computedSampleSize == 1) {
88 REPORTER_ASSERT(r, size == dims);
89 } else {
90 REPORTER_ASSERT(r, computedSampleSize > 1);
91 if (size.width() >= dims.width() || size.height() >= dims.height()) {
92 ERRORF(r, "File %s's computed sample size (%i) is bigger than"
93 " original? original: %i x %i\tsampled: %i x %i",
94 file, computedSampleSize, dims.width(), dims.height(),
95 size.width(), size.height());
96 }
97 REPORTER_ASSERT(r, size.width() >= requested.width() &&
98 size.height() >= requested.height());
99 REPORTER_ASSERT(r, size.width() < dims.width() &&
100 size.height() < dims.height());
101 }
102 }
103
104 const SkISize upscales[] = {
105 dims, plus(dims, 5), times(dims, 2),
106 };
107 for (SkISize size : upscales) {
108 const int computedSampleSize = codec->computeSampleSize(&size);
109 REPORTER_ASSERT(r, computedSampleSize == 1);
110 REPORTER_ASSERT(r, dims == size);
111 }
112
113 // This mimics how Android's ImageDecoder uses SkAndroidCodec. A client
114 // can choose their dimensions based on calling getSampledDimensions,
115 // but the ImageDecoder API takes an arbitrary size. It then uses
116 // computeSampleSize to determine the best dimensions and sampleSize.
117 // It should return the same dimensions. the sampleSize may be different
118 // due to integer division.
119 for (int sampleSize : { 1, 2, 3, 4, 8, 16, 32 }) {
120 const SkISize sampledDims = codec->getSampledDimensions(sampleSize);
121 SkISize size = sampledDims;
122 const int computedSampleSize = codec->computeSampleSize(&size);
123 if (sampledDims != size) {
124 ERRORF(r, "File '%s'->getSampledDimensions(%i) yields computed"
125 " sample size of %i\n\tsampledDimensions: %i x %i\t"
126 "computed dimensions: %i x %i",
127 file, sampleSize, computedSampleSize,
128 sampledDims.width(), sampledDims.height(),
129 size.width(), size.height());
130 }
131 }
132 }
133}
static SkISize plus(const SkISize &size, int term)
static bool invalid(const SkISize &size)
static SkISize times(const SkISize &size, float factor)
sk_sp< SkData > GetResourceAsData(const char *resource)
Definition Resources.cpp:42
SkString GetResourcePath(const char *resource)
Definition Resources.cpp:23
#define REPORTER_ASSERT(r, cond,...)
Definition Test.h:286
#define ERRORF(r,...)
Definition Test.h:293
static std::unique_ptr< SkAndroidCodec > MakeFromCodec(std::unique_ptr< SkCodec >)
static std::unique_ptr< SkCodec > MakeFromData(sk_sp< SkData >, SkSpan< const SkCodecs::Decoder > decoders, SkPngChunkReader *=nullptr)
Definition SkCodec.cpp:241
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
Definition switches.h:41
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition switches.h:259
constexpr int32_t width() const
Definition SkSize.h:36
constexpr int32_t height() const
Definition SkSize.h:37

◆ DEF_TEST() [2/5]

DEF_TEST ( AndroidCodec_HLG  ,
 
)

Definition at line 204 of file AndroidCodecTest.cpp.

204 {
205 if (GetResourcePath().isEmpty()) {
206 return;
207 }
208
209 const char* path = "images/red-hlg-profile.png";
210 auto data = GetResourceAsData(path);
211 if (!data) {
212 ERRORF(r, "Missing file %s", path);
213 return;
214 }
215
216 auto codec = SkAndroidCodec::MakeFromCodec(SkCodec::MakeFromData(std::move(data)));
217 if (!codec) {
218 ERRORF(r, "Failed to create codec from %s", path);
219 return;
220 }
221
222 auto info = codec->getInfo();
223 auto cs = codec->computeOutputColorSpace(info.colorType(), nullptr);
224 if (!cs) {
225 ERRORF(r, "%s should have a color space", path);
226 return;
227 }
228
230 cs->transferFn(&tf);
232
234 cs->toXYZD50(&matrix);
235
236 static constexpr skcms_Matrix3x3 kExpected = SkNamedGamut::kRec2020;
237 REPORTER_ASSERT(r, 0 == memcmp(&matrix, &kExpected, sizeof(skcms_Matrix3x3)));
238}
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition DM.cpp:213
static constexpr skcms_Matrix3x3 kRec2020
unsigned useCenter Optional< SkMatrix > matrix
Definition SkRecords.h:258
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
bool skcms_TransferFunction_isHLGish(const skcms_TransferFunction *tf)
Definition skcms.cc:192

◆ DEF_TEST() [3/5]

DEF_TEST ( AndroidCodec_P3  ,
 
)

Definition at line 165 of file AndroidCodecTest.cpp.

165 {
166 if (GetResourcePath().isEmpty()) {
167 return;
168 }
169
170 const char* path = "images/purple-displayprofile.png";
171 auto data = GetResourceAsData(path);
172 if (!data) {
173 ERRORF(r, "Missing file %s", path);
174 return;
175 }
176
177 auto codec = SkAndroidCodec::MakeFromCodec(SkCodec::MakeFromData(std::move(data)));
178 if (!codec) {
179 ERRORF(r, "Failed to create codec from %s", path);
180 return;
181 }
182
183 auto info = codec->getInfo();
184 auto cs = codec->computeOutputColorSpace(info.colorType(), nullptr);
185 if (!cs) {
186 ERRORF(r, "%s should have a color space", path);
187 return;
188 }
189
190 REPORTER_ASSERT(r, !cs->isSRGB());
191 REPORTER_ASSERT(r, cs->gammaCloseToSRGB());
192
194 cs->toXYZD50(&matrix);
195
196 static constexpr skcms_Matrix3x3 kExpected = {{
197 { 0.426254272f, 0.369018555f, 0.168914795f },
198 { 0.226013184f, 0.685974121f, 0.0880126953f },
199 { 0.0116729736f, 0.0950927734f, 0.71812439f },
200 }};
201 REPORTER_ASSERT(r, 0 == memcmp(&matrix, &kExpected, sizeof(skcms_Matrix3x3)));
202}

◆ DEF_TEST() [4/5]

DEF_TEST ( AndroidCodec_PQ  ,
 
)

Definition at line 240 of file AndroidCodecTest.cpp.

240 {
241 if (GetResourcePath().isEmpty()) {
242 return;
243 }
244
245 const char* path = "images/red-pq-profile.png";
246 auto data = GetResourceAsData(path);
247 if (!data) {
248 ERRORF(r, "Missing file %s", path);
249 return;
250 }
251
252 auto codec = SkAndroidCodec::MakeFromCodec(SkCodec::MakeFromData(std::move(data)));
253 if (!codec) {
254 ERRORF(r, "Failed to create codec from %s", path);
255 return;
256 }
257
258 auto info = codec->getInfo();
259 auto cs = codec->computeOutputColorSpace(info.colorType(), nullptr);
260 if (!cs) {
261 ERRORF(r, "%s should have a color space", path);
262 return;
263 }
264
266 cs->transferFn(&tf);
268
270 cs->toXYZD50(&matrix);
271
272 static constexpr skcms_Matrix3x3 kExpected = SkNamedGamut::kRec2020;
273 REPORTER_ASSERT(r, 0 == memcmp(&matrix, &kExpected, sizeof(skcms_Matrix3x3)));
274}
bool skcms_TransferFunction_isPQish(const skcms_TransferFunction *tf)
Definition skcms.cc:189

◆ DEF_TEST() [5/5]

DEF_TEST ( AndroidCodec_wide  ,
 
)

Definition at line 135 of file AndroidCodecTest.cpp.

135 {
136 if (GetResourcePath().isEmpty()) {
137 return;
138 }
139
140 const char* path = "images/wide-gamut.png";
141 auto data = GetResourceAsData(path);
142 if (!data) {
143 ERRORF(r, "Missing file %s", path);
144 return;
145 }
146
147 auto codec = SkAndroidCodec::MakeFromCodec(SkCodec::MakeFromData(std::move(data)));
148 if (!codec) {
149 ERRORF(r, "Failed to create codec from %s", path);
150 return;
151 }
152
153 auto info = codec->getInfo();
154 auto cs = codec->computeOutputColorSpace(info.colorType(), nullptr);
155 if (!cs) {
156 ERRORF(r, "%s should have a color space", path);
157 return;
158 }
159
160 // This image has a gamut that is VERY close to sRGB, so SkColorSpace::MakeRGB snaps to sRGB.
161 auto expected = SkColorSpace::MakeSRGB();
162 REPORTER_ASSERT(r, SkColorSpace::Equals(cs.get(), expected.get()));
163}
static bool Equals(const SkColorSpace *, const SkColorSpace *)
static sk_sp< SkColorSpace > MakeSRGB()

◆ invalid()

static bool invalid ( const SkISize size)
static

Definition at line 37 of file AndroidCodecTest.cpp.

37 {
38 return size.width() < 1 || size.height() < 1;
39}

◆ plus()

static SkISize plus ( const SkISize size,
int  term 
)
static

Definition at line 33 of file AndroidCodecTest.cpp.

33 {
34 return { size.width() + term, size.height() + term };
35}

◆ times()

static SkISize times ( const SkISize size,
float  factor 
)
static

Definition at line 29 of file AndroidCodecTest.cpp.

29 {
30 return { (int) (size.width() * factor), (int) (size.height() * factor) };
31}
Type::kYUV Type::kRGBA() int(0.7 *637)