1 /*
2 * Copyright 2020 Google LLC
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 "include/core/SkTypes.h"
9 #ifdef SK_ENABLE_NDK_IMAGES
10 #include "include/codec/SkEncodedImageFormat.h"
11 #include "include/core/SkBitmap.h"
12 #include "include/core/SkColorSpace.h"
13 #include "include/core/SkStream.h"
14 #include "include/encode/SkJpegEncoder.h"
15 #include "include/encode/SkPngEncoder.h"
16 #include "include/encode/SkWebpEncoder.h"
17 #include "include/ports/SkImageGeneratorNDK.h"
18
19 #include "tests/Test.h"
20 #include "tools/Resources.h"
21 #include "tools/ToolUtils.h"
22
23 #include <vector>
24
make_generator(const char * path,skiatest::Reporter * r)25 static std::unique_ptr<SkImageGenerator> make_generator(const char* path, skiatest::Reporter* r) {
26 auto data = GetResourceAsData(path);
27 if (data) {
28 auto gen = SkImageGeneratorNDK::MakeFromEncodedNDK(std::move(data));
29 if (gen) {
30 return gen;
31 }
32 ERRORF(r, "Failed to create NDK generator from %s\n", path);
33 } else {
34 // Silently fail so developers can skip using --resources
35 }
36 return nullptr;
37 }
38
DEF_TEST(NdkDecode,r)39 DEF_TEST(NdkDecode, r) {
40 static const struct {
41 const char* fPath;
42 SkISize fSize;
43 } recs[] = {
44 {"images/CMYK.jpg", {642, 516}},
45 {"images/arrow.png", {187, 312}},
46 {"images/baby_tux.webp", {386, 395}},
47 {"images/color_wheel.gif", {128, 128}},
48 {"images/rle.bmp", {320, 240}},
49 {"images/color_wheel.ico", {128, 128}},
50 {"images/google_chrome.ico", {256, 256}},
51 {"images/mandrill.wbmp", {512, 512}},
52 };
53 for (auto& rec : recs) {
54 auto gen = make_generator(rec.fPath, r);
55 if (!gen) continue;
56
57 const auto& info = gen->getInfo();
58 REPORTER_ASSERT(r, info.dimensions() == rec.fSize);
59
60 SkBitmap bm;
61 bm.allocPixels(info);
62 REPORTER_ASSERT(r, gen->getPixels(bm.pixmap()));
63
64 REPORTER_ASSERT(r, info.alphaType() != kUnpremul_SkAlphaType);
65 auto unpremulInfo = info.makeAlphaType(kUnpremul_SkAlphaType);
66 bm.allocPixels(unpremulInfo);
67 REPORTER_ASSERT(r, gen->getPixels(bm.pixmap()));
68 }
69 }
70
DEF_TEST(NdkDecode_nullData,r)71 DEF_TEST(NdkDecode_nullData, r) {
72 auto gen = SkImageGeneratorNDK::MakeFromEncodedNDK(nullptr);
73 REPORTER_ASSERT(r, !gen);
74 }
75
76 static constexpr skcms_TransferFunction k2Dot6 = {2.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
77
78 static constexpr skcms_Matrix3x3 kDCIP3 = {{
79 {0.486143, 0.323835, 0.154234},
80 {0.226676, 0.710327, 0.0629966},
81 {0.000800549, 0.0432385, 0.78275},
82 }};
83
DEF_TEST(NdkDecode_reportedColorSpace,r)84 DEF_TEST(NdkDecode_reportedColorSpace, r) {
85 for (sk_sp<SkColorSpace> cs : {
86 sk_sp<SkColorSpace>(nullptr),
87 SkColorSpace::MakeSRGB(),
88 SkColorSpace::MakeSRGBLinear(),
89 SkColorSpace::MakeRGB(SkNamedTransferFn::kRec2020, SkNamedGamut::kSRGB),
90 SkColorSpace::MakeRGB(SkNamedTransferFn::kRec2020, SkNamedGamut::kRec2020),
91 SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, SkNamedGamut::kDisplayP3),
92 SkColorSpace::MakeRGB(SkNamedTransferFn::k2Dot2, SkNamedGamut::kAdobeRGB),
93 SkColorSpace::MakeRGB(k2Dot6, kDCIP3),
94 }) {
95 SkBitmap bm;
96 bm.allocPixels(SkImageInfo::Make(10, 10, kRGBA_F16_SkColorType, kOpaque_SkAlphaType, cs));
97 bm.eraseColor(SK_ColorBLUE);
98
99 for (auto format : { SkEncodedImageFormat::kPNG,
100 SkEncodedImageFormat::kJPEG,
101 SkEncodedImageFormat::kWEBP }) {
102 SkDynamicMemoryWStream stream;
103 if (format == SkEncodedImageFormat::kJPEG) {
104 SkJpegEncoder::Options opts;
105 opts.fQuality = 80;
106 REPORTER_ASSERT(r, SkJpegEncoder::Encode(&stream, bm.pixmap(), opts));
107 } else if (format == SkEncodedImageFormat::kPNG) {
108 REPORTER_ASSERT(r, SkPngEncoder::Encode(&stream, bm.pixmap(), {}));
109 } else {
110 SkWebpEncoder::Options opts;
111 opts.fQuality = 80;
112 REPORTER_ASSERT(r, SkWebpEncoder::Encode(&stream, bm.pixmap(), opts));
113 }
114
115 auto gen = SkImageGeneratorNDK::MakeFromEncodedNDK(stream.detachAsData());
116 if (!gen) {
117 ERRORF(r, "Failed to encode!");
118 return;
119 }
120
121 if (!cs) cs = SkColorSpace::MakeSRGB();
122 REPORTER_ASSERT(r, SkColorSpace::Equals(gen->getInfo().colorSpace(), cs.get()));
123 }
124 }
125 }
126
DEF_TEST(NdkDecode_ColorSpace,r)127 DEF_TEST(NdkDecode_ColorSpace, r) {
128 for (const char* path: {
129 "images/CMYK.jpg",
130 "images/arrow.png",
131 "images/baby_tux.webp",
132 "images/color_wheel.gif",
133 "images/rle.bmp",
134 "images/color_wheel.ico",
135 "images/google_chrome.ico",
136 "images/mandrill.wbmp",
137 }) {
138 auto gen = make_generator(path, r);
139 if (!gen) continue;
140
141 for (sk_sp<SkColorSpace> cs : {
142 sk_sp<SkColorSpace>(nullptr),
143 SkColorSpace::MakeSRGB(),
144 SkColorSpace::MakeSRGBLinear(),
145 SkColorSpace::MakeRGB(SkNamedTransferFn::kRec2020, SkNamedGamut::kSRGB),
146 SkColorSpace::MakeRGB(SkNamedTransferFn::kRec2020, SkNamedGamut::kRec2020),
147 SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, SkNamedGamut::kDisplayP3),
148 SkColorSpace::MakeRGB(SkNamedTransferFn::k2Dot2, SkNamedGamut::kAdobeRGB),
149 SkColorSpace::MakeRGB(k2Dot6, kDCIP3),
150 }) {
151 auto info = gen->getInfo().makeColorSpace(cs);
152
153 SkBitmap bm;
154 bm.allocPixels(info);
155 REPORTER_ASSERT(r, gen->getPixels(bm.pixmap()));
156 }
157
158 std::vector<sk_sp<SkColorSpace>> unsupportedCs;
159 for (auto gamut : { SkNamedGamut::kSRGB, SkNamedGamut::kAdobeRGB, SkNamedGamut::kDisplayP3,
160 SkNamedGamut::kRec2020, SkNamedGamut::kXYZ }) {
161 unsupportedCs.push_back(SkColorSpace::MakeRGB(SkNamedTransferFn::kPQ, gamut));
162 unsupportedCs.push_back(SkColorSpace::MakeRGB(SkNamedTransferFn::kHLG, gamut));
163 unsupportedCs.push_back(SkColorSpace::MakeRGB(k2Dot6, gamut));
164 }
165
166 for (auto gamut : { SkNamedGamut::kSRGB, SkNamedGamut::kDisplayP3,
167 SkNamedGamut::kRec2020, SkNamedGamut::kXYZ }) {
168 unsupportedCs.push_back(SkColorSpace::MakeRGB(SkNamedTransferFn::k2Dot2, gamut));
169 }
170
171 for (auto gamut : { SkNamedGamut::kAdobeRGB, SkNamedGamut::kDisplayP3,
172 SkNamedGamut::kXYZ }) {
173 unsupportedCs.push_back(SkColorSpace::MakeRGB(SkNamedTransferFn::kRec2020, gamut));
174 }
175
176 for (auto gamut : { SkNamedGamut::kAdobeRGB, SkNamedGamut::kDisplayP3,
177 SkNamedGamut::kRec2020, SkNamedGamut::kXYZ }) {
178 unsupportedCs.push_back(SkColorSpace::MakeRGB(SkNamedTransferFn::kLinear, gamut));
179 }
180
181 for (auto gamut : { SkNamedGamut::kAdobeRGB,
182 SkNamedGamut::kRec2020, SkNamedGamut::kXYZ }) {
183 unsupportedCs.push_back(SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, gamut));
184 }
185
186 for (auto fn : { SkNamedTransferFn::kSRGB, SkNamedTransferFn::k2Dot2,
187 SkNamedTransferFn::kLinear, SkNamedTransferFn::kRec2020 }) {
188 unsupportedCs.push_back(SkColorSpace::MakeRGB(fn, kDCIP3));
189 }
190
191 for (auto unsupported : unsupportedCs) {
192 auto info = gen->getInfo().makeColorSpace(unsupported);
193
194 SkBitmap bm;
195 bm.allocPixels(info);
196 REPORTER_ASSERT(r, !gen->getPixels(bm.pixmap()));
197 }
198 }
199 }
200
DEF_TEST(NdkDecode_reuseNoColorSpace,r)201 DEF_TEST(NdkDecode_reuseNoColorSpace, r) {
202 static const struct {
203 const char* fPath;
204 sk_sp<SkColorSpace> fCorrectedColorSpace;
205 bool fIsOpaque;
206 } recs[] = {
207 // AImageDecoder defaults to ADATASPACE_UNKNOWN for this image.
208 {"images/wide_gamut_yellow_224_224_64.jpeg", SkColorSpace::MakeSRGB(), true},
209 // This image is SRGB, so convert to a different color space.
210 {"images/example_1.png", SkColorSpace::MakeRGB(SkNamedTransferFn::k2Dot2,
211 SkNamedGamut::kAdobeRGB), false},
212 };
213 for (auto& rec : recs) {
214 auto gen = make_generator(rec.fPath, r);
215 if (!gen) continue;
216
217 REPORTER_ASSERT(r, gen->getInfo().colorSpace()->isSRGB());
218 REPORTER_ASSERT(r, gen->getInfo().isOpaque() == rec.fIsOpaque);
219
220 auto noColorCorrection = gen->getInfo().makeColorSpace(nullptr);
221 if (rec.fIsOpaque) {
222 // Use something other than the default color type to verify that the modified color
223 // type is used even when the color space is reset.
224 noColorCorrection = noColorCorrection.makeColorType(kRGB_565_SkColorType);
225 }
226
227 SkBitmap orig;
228 orig.allocPixels(noColorCorrection);
229 REPORTER_ASSERT(r, gen->getPixels(orig.pixmap()));
230
231 SkBitmap corrected;
232 corrected.allocPixels(noColorCorrection.makeColorSpace(rec.fCorrectedColorSpace));
233 REPORTER_ASSERT(r, gen->getPixels(corrected.pixmap()));
234
235 REPORTER_ASSERT(r, !ToolUtils::equal_pixels(orig, corrected));
236
237 SkBitmap reuse;
238 reuse.allocPixels(noColorCorrection);
239 REPORTER_ASSERT(r, gen->getPixels(reuse.pixmap()));
240
241 REPORTER_ASSERT(r, ToolUtils::equal_pixels(orig, reuse));
242 }
243 }
244
245 // The NDK supports scaling up to arbitrary dimensions. Skia forces clients to do this in a
246 // separate step, so the client is in charge of how to do the upscale.
DEF_TEST(NdkDecode_noUpscale,r)247 DEF_TEST(NdkDecode_noUpscale, r) {
248 for (const char* path: {
249 "images/CMYK.jpg",
250 "images/arrow.png",
251 "images/baby_tux.webp",
252 "images/color_wheel.gif",
253 "images/rle.bmp",
254 "images/color_wheel.ico",
255 "images/google_chrome.ico",
256 "images/mandrill.wbmp",
257 }) {
258 auto gen = make_generator(path, r);
259 if (!gen) continue;
260
261 const auto actualDimensions = gen->getInfo().dimensions();
262 const int width = actualDimensions.width();
263 const int height = actualDimensions.height();
264 for (SkISize dims : {
265 SkISize{width*2, height*2},
266 SkISize{width + 1, height + 1},
267 }) {
268 auto info = gen->getInfo().makeDimensions(dims);
269 SkBitmap bm;
270 bm.allocPixels(info);
271 REPORTER_ASSERT(r, !gen->getPixels(bm.pixmap()));
272 }
273 }
274 }
275
276 // libwebp supports downscaling to an arbitrary scale factor, and this is supported by the NDK.
DEF_TEST(NdkDecode_webpArbitraryDownscale,r)277 DEF_TEST(NdkDecode_webpArbitraryDownscale, r) {
278 for (const char* path: {
279 "images/baby_tux.webp",
280 "images/yellow_rose.webp",
281 "images/webp-color-profile-lossless.webp",
282 }) {
283 auto gen = make_generator(path, r);
284 if (!gen) continue;
285
286 const auto actualDimensions = gen->getInfo().dimensions();
287 const int width = actualDimensions.width();
288 const int height = actualDimensions.height();
289 for (SkISize dims : {
290 SkISize{width/2, height/2},
291 SkISize{width/4, height/4},
292 SkISize{width/7, height/7},
293 SkISize{width - 1, height - 1},
294 SkISize{1, 1},
295 SkISize{5, 20}
296 }) {
297 auto info = gen->getInfo().makeDimensions(dims);
298 SkBitmap bm;
299 bm.allocPixels(info);
300 REPORTER_ASSERT(r, gen->getPixels(bm.pixmap()));
301
302 REPORTER_ASSERT(r, info.alphaType() != kUnpremul_SkAlphaType);
303 auto unpremulInfo = info.makeAlphaType(kUnpremul_SkAlphaType);
304 bm.allocPixels(unpremulInfo);
305 REPORTER_ASSERT(r, gen->getPixels(bm.pixmap()));
306 }
307 }
308 }
309
310 // libjpeg-turbo supports downscaling to some scale factors.
DEF_TEST(NdkDecode_jpegDownscale,r)311 DEF_TEST(NdkDecode_jpegDownscale, r) {
312 static const struct {
313 const char* fPath;
314 SkISize fSupportedSizes[4];
315 } recs[] = {
316 {"images/CMYK.jpg", {{642,516},{321,258},{161,129},{81,65}}},
317 {"images/dog.jpg", {{180,180},{90,90},{45,45},{23,23}}},
318 {"images/grayscale.jpg", {{128,128},{64,64},{32,32},{16,16}}},
319 {"images/brickwork-texture.jpg", {{512,512},{256,256},{128,128},{64,64}}},
320 {"images/mandrill_h2v1.jpg", {{512,512},{256,256},{128,128},{64,64}}},
321 {"images/ducky.jpg", {{489,537},{245,269},{123,135},{62,68}}},
322 };
323 for (auto& rec : recs) {
324 auto gen = make_generator(rec.fPath, r);
325 if (!gen) continue;
326
327 for (SkISize dims : rec.fSupportedSizes) {
328 auto info = gen->getInfo().makeDimensions(dims);
329 SkBitmap bm;
330 bm.allocPixels(info);
331 if (!gen->getPixels(bm.pixmap())) {
332 ERRORF(r, "failed to decode %s to {%i,%i}\n", rec.fPath, dims.width(),
333 dims.height());
334 }
335
336 REPORTER_ASSERT(r, info.alphaType() != kUnpremul_SkAlphaType);
337 auto unpremulInfo = info.makeAlphaType(kUnpremul_SkAlphaType);
338 bm.allocPixels(unpremulInfo);
339 REPORTER_ASSERT(r, gen->getPixels(bm.pixmap()));
340 }
341 }
342 }
343
DEF_TEST(NdkDecode_reuseJpeg,r)344 DEF_TEST(NdkDecode_reuseJpeg, r) {
345 auto gen = make_generator("images/CMYK.jpg", r);
346 if (!gen) return;
347
348 SkImageInfo info = gen->getInfo();
349 SkBitmap orig;
350 orig.allocPixels(info);
351 REPORTER_ASSERT(r, gen->getPixels(orig.pixmap()));
352
353 info = info.makeWH(321, 258);
354 SkBitmap downscaled;
355 downscaled.allocPixels(info);
356 REPORTER_ASSERT(r, gen->getPixels(downscaled.pixmap()));
357
358 SkBitmap reuse;
359 reuse.allocPixels(gen->getInfo());
360 REPORTER_ASSERT(r, gen->getPixels(reuse.pixmap()));
361
362 REPORTER_ASSERT(r, ToolUtils::equal_pixels(orig, reuse));
363 }
364
365 // The NDK supports scaling down to arbitrary dimensions. Skia forces clients to do this in a
366 // separate step, so the client is in charge of how to do the downscale.
DEF_TEST(NdkDecode_noDownscale,r)367 DEF_TEST(NdkDecode_noDownscale, r) {
368 for (const char* path: {
369 "images/arrow.png",
370 "images/color_wheel.gif",
371 "images/rle.bmp",
372 "images/color_wheel.ico",
373 "images/google_chrome.ico",
374 "images/mandrill.wbmp",
375 }) {
376 auto gen = make_generator(path, r);
377 if (!gen) continue;
378
379 const auto actualDimensions = gen->getInfo().dimensions();
380 const int width = actualDimensions.width();
381 const int height = actualDimensions.height();
382 for (SkISize dims : {
383 SkISize{width/2, height/2},
384 SkISize{width/3, height/3},
385 SkISize{width/4, height/4},
386 SkISize{width/8, height/8},
387 SkISize{width - 1, height - 1},
388 }) {
389 auto info = gen->getInfo().makeDimensions(dims);
390 SkBitmap bm;
391 bm.allocPixels(info);
392 REPORTER_ASSERT(r, !gen->getPixels(bm.pixmap()));
393 }
394 }
395 }
396
DEF_TEST(NdkDecode_Gray8,r)397 DEF_TEST(NdkDecode_Gray8, r) {
398 static const struct {
399 const char* fPath;
400 bool fGrayscale;
401 } recs[] = {
402 {"images/CMYK.jpg", false},
403 {"images/arrow.png", false},
404 {"images/baby_tux.webp", false},
405 {"images/color_wheel.gif", false},
406 {"images/rle.bmp", false},
407 {"images/color_wheel.ico", false},
408 {"images/google_chrome.ico", false},
409 {"images/mandrill.wbmp", true},
410 {"images/grayscale.jpg", true},
411 {"images/grayscale.png", true},
412 };
413 for (auto& rec : recs) {
414 auto gen = make_generator(rec.fPath, r);
415 if (!gen) continue;
416
417 SkImageInfo info = gen->getInfo();
418 if (rec.fGrayscale) {
419 REPORTER_ASSERT(r, info.colorType() == kGray_8_SkColorType);
420 REPORTER_ASSERT(r, info.alphaType() == kOpaque_SkAlphaType);
421 } else {
422 info = info.makeColorType(kGray_8_SkColorType);
423 }
424 SkBitmap bm;
425 bm.allocPixels(info);
426 bool success = gen->getPixels(bm.pixmap());
427 if (success != rec.fGrayscale) {
428 ERRORF(r, "Expected decoding %s to Gray8 to %s. Actual: %s\n", rec.fPath,
429 (rec.fGrayscale ? "succeed" : "fail"), (success ? "succeed" : "fail"));
430 }
431 }
432 }
433
DEF_TEST(NdkDecode_Opaque_and_565,r)434 DEF_TEST(NdkDecode_Opaque_and_565, r) {
435 for (const char* path: {
436 "images/CMYK.jpg",
437 "images/dog.jpg",
438 "images/ducky.jpg",
439 "images/arrow.png",
440 "images/example_1.png",
441 "images/explosion_sprites.png",
442 "images/lut_identity.png",
443 "images/grayscale.png",
444 "images/baby_tux.webp",
445 "images/yellow_rose.webp",
446 "images/webp-color-profile-lossless.webp",
447 "images/colorTables.gif",
448 "images/color_wheel.gif",
449 "images/flightAnim.gif",
450 "images/randPixels.gif",
451 "images/rle.bmp",
452 "images/color_wheel.ico",
453 "images/google_chrome.ico",
454 "images/mandrill.wbmp",
455 }) {
456 auto gen = make_generator(path, r);
457 if (!gen) continue;
458
459 auto info = gen->getInfo().makeAlphaType(kOpaque_SkAlphaType);
460 SkBitmap bm;
461 bm.allocPixels(info);
462 bool success = gen->getPixels(bm.pixmap());
463 REPORTER_ASSERT(r, success == gen->getInfo().isOpaque());
464
465 info = info.makeColorType(kRGB_565_SkColorType);
466 bm.allocPixels(info);
467 success = gen->getPixels(bm.pixmap());
468 REPORTER_ASSERT(r, success == gen->getInfo().isOpaque());
469 }
470 }
471
DEF_TEST(NdkDecode_AlwaysSupportedColorTypes,r)472 DEF_TEST(NdkDecode_AlwaysSupportedColorTypes, r) {
473 for (const char* path: {
474 "images/CMYK.jpg",
475 "images/dog.jpg",
476 "images/ducky.jpg",
477 "images/arrow.png",
478 "images/example_1.png",
479 "images/explosion_sprites.png",
480 "images/lut_identity.png",
481 "images/grayscale.png",
482 "images/baby_tux.webp",
483 "images/yellow_rose.webp",
484 "images/webp-color-profile-lossless.webp",
485 "images/colorTables.gif",
486 "images/color_wheel.gif",
487 "images/flightAnim.gif",
488 "images/randPixels.gif",
489 "images/rle.bmp",
490 "images/color_wheel.ico",
491 "images/google_chrome.ico",
492 "images/mandrill.wbmp",
493 }) {
494 auto gen = make_generator(path, r);
495 if (!gen) continue;
496
497 auto info = gen->getInfo().makeColorType(kRGBA_F16_SkColorType);
498 SkBitmap bm;
499 bm.allocPixels(info);
500 REPORTER_ASSERT(r, gen->getPixels(bm.pixmap()));
501
502 // This also tests that we can reuse the same generator for a different
503 // color type.
504 info = info.makeColorType(kRGBA_8888_SkColorType);
505 bm.allocPixels(info);
506 REPORTER_ASSERT(r, gen->getPixels(bm.pixmap()));
507 }
508 }
509
DEF_TEST(NdkDecode_UnsupportedColorTypes,r)510 DEF_TEST(NdkDecode_UnsupportedColorTypes, r) {
511 for (const char* path: {
512 "images/CMYK.jpg",
513 "images/dog.jpg",
514 "images/ducky.jpg",
515 "images/arrow.png",
516 "images/example_1.png",
517 "images/explosion_sprites.png",
518 "images/lut_identity.png",
519 "images/grayscale.png",
520 "images/baby_tux.webp",
521 "images/yellow_rose.webp",
522 "images/webp-color-profile-lossless.webp",
523 "images/colorTables.gif",
524 "images/color_wheel.gif",
525 "images/flightAnim.gif",
526 "images/randPixels.gif",
527 "images/rle.bmp",
528 "images/color_wheel.ico",
529 "images/google_chrome.ico",
530 "images/mandrill.wbmp",
531 }) {
532 auto gen = make_generator(path, r);
533 if (!gen) continue;
534
535 for (SkColorType ct : {
536 kUnknown_SkColorType,
537 kAlpha_8_SkColorType,
538 kARGB_4444_SkColorType,
539 kRGB_888x_SkColorType,
540 kBGRA_8888_SkColorType,
541 kRGBA_1010102_SkColorType,
542 kBGRA_1010102_SkColorType,
543 kRGB_101010x_SkColorType,
544 kBGR_101010x_SkColorType,
545 kRGBA_F16Norm_SkColorType,
546 kRGB_F16F16F16x_SkColorType,
547 kRGBA_F32_SkColorType,
548 kR8G8_unorm_SkColorType,
549 kA16_float_SkColorType,
550 kR16G16_float_SkColorType,
551 kA16_unorm_SkColorType,
552 kR16G16_unorm_SkColorType,
553 kR16G16B16A16_unorm_SkColorType,
554 }) {
555 auto info = gen->getInfo().makeColorType(ct);
556 SkBitmap bm;
557 bm.allocPixels(info);
558 if (gen->getPixels(bm.pixmap())) {
559 ERRORF(r, "Expected decoding %s to %i to fail!", path, ct);
560 }
561 }
562 }
563 }
564 #endif // SK_ENABLE_NDK_IMAGES
565