| /* | 
 |  * Copyright 2020 Google LLC | 
 |  * | 
 |  * Use of this source code is governed by a BSD-style license that can be | 
 |  * found in the LICENSE file. | 
 |  */ | 
 |  | 
 | #include "include/core/SkTypes.h" | 
 | #ifdef SK_ENABLE_NDK_IMAGES | 
 | #include "include/ports/SkImageGeneratorNDK.h" | 
 | #include "tests/Test.h" | 
 | #include "tools/Resources.h" | 
 | #include "tools/ToolUtils.h" | 
 |  | 
 | #include <vector> | 
 |  | 
 | static std::unique_ptr<SkImageGenerator> make_generator(const char* path, skiatest::Reporter* r) { | 
 |     auto data = GetResourceAsData(path); | 
 |     if (data) { | 
 |         auto gen = SkImageGeneratorNDK::MakeFromEncodedNDK(std::move(data)); | 
 |         if (gen) { | 
 |             return gen; | 
 |         } | 
 |         ERRORF(r, "Failed to create NDK generator from %s\n", path); | 
 |     } else { | 
 |         // Silently fail so developers can skip using --resources | 
 |     } | 
 |     return nullptr; | 
 | } | 
 |  | 
 | DEF_TEST(NdkDecode, r) { | 
 |     static const struct { | 
 |         const char* fPath; | 
 |         SkISize     fSize; | 
 |     } recs[] = { | 
 |         {"images/CMYK.jpg", {642, 516}}, | 
 |         {"images/arrow.png", {187, 312}}, | 
 |         {"images/baby_tux.webp", {386, 395}}, | 
 |         {"images/color_wheel.gif", {128, 128}}, | 
 |         {"images/rle.bmp", {320, 240}}, | 
 |         {"images/color_wheel.ico", {128, 128}}, | 
 |         {"images/google_chrome.ico", {256, 256}}, | 
 |         {"images/mandrill.wbmp", {512, 512}}, | 
 |     }; | 
 |     for (auto& rec : recs) { | 
 |         auto gen = make_generator(rec.fPath, r); | 
 |         if (!gen) continue; | 
 |  | 
 |         const auto& info = gen->getInfo(); | 
 |         REPORTER_ASSERT(r, info.dimensions() == rec.fSize); | 
 |  | 
 |         SkBitmap bm; | 
 |         bm.allocPixels(info); | 
 |         REPORTER_ASSERT(r, gen->getPixels(bm.pixmap())); | 
 |  | 
 |         REPORTER_ASSERT(r, info.alphaType() != kUnpremul_SkAlphaType); | 
 |         auto unpremulInfo = info.makeAlphaType(kUnpremul_SkAlphaType); | 
 |         bm.allocPixels(unpremulInfo); | 
 |         REPORTER_ASSERT(r, gen->getPixels(bm.pixmap())); | 
 |     } | 
 | } | 
 |  | 
 | DEF_TEST(NdkDecode_nullData, r) { | 
 |     auto gen = SkImageGeneratorNDK::MakeFromEncodedNDK(nullptr); | 
 |     REPORTER_ASSERT(r, !gen); | 
 | } | 
 |  | 
 | static constexpr skcms_TransferFunction k2Dot6 = {2.6f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}; | 
 |  | 
 | static constexpr skcms_Matrix3x3 kDCIP3 = {{ | 
 |         {0.486143, 0.323835, 0.154234}, | 
 |         {0.226676, 0.710327, 0.0629966}, | 
 |         {0.000800549, 0.0432385, 0.78275}, | 
 | }}; | 
 |  | 
 | DEF_TEST(NdkDecode_reportedColorSpace, r) { | 
 |     for (sk_sp<SkColorSpace> cs : { | 
 |         sk_sp<SkColorSpace>(nullptr), | 
 |         SkColorSpace::MakeSRGB(), | 
 |         SkColorSpace::MakeSRGBLinear(), | 
 |         SkColorSpace::MakeRGB(SkNamedTransferFn::kRec2020, SkNamedGamut::kSRGB), | 
 |         SkColorSpace::MakeRGB(SkNamedTransferFn::kRec2020, SkNamedGamut::kRec2020), | 
 |         SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, SkNamedGamut::kDisplayP3), | 
 |         SkColorSpace::MakeRGB(SkNamedTransferFn::k2Dot2, SkNamedGamut::kAdobeRGB), | 
 |         SkColorSpace::MakeRGB(k2Dot6, kDCIP3), | 
 |     }) { | 
 |         SkBitmap bm; | 
 |         bm.allocPixels(SkImageInfo::Make(10, 10, kRGBA_F16_SkColorType, kOpaque_SkAlphaType, cs)); | 
 |         bm.eraseColor(SK_ColorBLUE); | 
 |  | 
 |         for (auto format : { SkEncodedImageFormat::kPNG, | 
 |                              SkEncodedImageFormat::kJPEG, | 
 |                              SkEncodedImageFormat::kWEBP }) { | 
 |             auto data = SkEncodeBitmap(bm, format, 80); | 
 |             auto gen = SkImageGeneratorNDK::MakeFromEncodedNDK(std::move(data)); | 
 |             if (!gen) { | 
 |                 ERRORF(r, "Failed to encode!"); | 
 |                 return; | 
 |             } | 
 |  | 
 |             if (!cs) cs = SkColorSpace::MakeSRGB(); | 
 |             REPORTER_ASSERT(r, SkColorSpace::Equals(gen->getInfo().colorSpace(), cs.get())); | 
 |         } | 
 |     } | 
 | } | 
 |  | 
 | DEF_TEST(NdkDecode_ColorSpace, r) { | 
 |     for (const char* path: { | 
 |         "images/CMYK.jpg", | 
 |         "images/arrow.png", | 
 |         "images/baby_tux.webp", | 
 |         "images/color_wheel.gif", | 
 |         "images/rle.bmp", | 
 |         "images/color_wheel.ico", | 
 |         "images/google_chrome.ico", | 
 |         "images/mandrill.wbmp", | 
 |     }) { | 
 |         auto gen = make_generator(path, r); | 
 |         if (!gen) continue; | 
 |  | 
 |         for (sk_sp<SkColorSpace> cs : { | 
 |             sk_sp<SkColorSpace>(nullptr), | 
 |             SkColorSpace::MakeSRGB(), | 
 |             SkColorSpace::MakeSRGBLinear(), | 
 |             SkColorSpace::MakeRGB(SkNamedTransferFn::kRec2020, SkNamedGamut::kSRGB), | 
 |             SkColorSpace::MakeRGB(SkNamedTransferFn::kRec2020, SkNamedGamut::kRec2020), | 
 |             SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, SkNamedGamut::kDisplayP3), | 
 |             SkColorSpace::MakeRGB(SkNamedTransferFn::k2Dot2, SkNamedGamut::kAdobeRGB), | 
 |             SkColorSpace::MakeRGB(k2Dot6, kDCIP3), | 
 |         }) { | 
 |             auto info = gen->getInfo().makeColorSpace(cs); | 
 |  | 
 |             SkBitmap bm; | 
 |             bm.allocPixels(info); | 
 |             REPORTER_ASSERT(r, gen->getPixels(bm.pixmap())); | 
 |         } | 
 |  | 
 |         std::vector<sk_sp<SkColorSpace>> unsupportedCs; | 
 |         for (auto gamut : { SkNamedGamut::kSRGB, SkNamedGamut::kAdobeRGB, SkNamedGamut::kDisplayP3, | 
 |                             SkNamedGamut::kRec2020, SkNamedGamut::kXYZ }) { | 
 |             unsupportedCs.push_back(SkColorSpace::MakeRGB(SkNamedTransferFn::kPQ, gamut)); | 
 |             unsupportedCs.push_back(SkColorSpace::MakeRGB(SkNamedTransferFn::kHLG, gamut)); | 
 |             unsupportedCs.push_back(SkColorSpace::MakeRGB(k2Dot6, gamut)); | 
 |         } | 
 |  | 
 |         for (auto gamut : { SkNamedGamut::kSRGB, SkNamedGamut::kDisplayP3, | 
 |                             SkNamedGamut::kRec2020, SkNamedGamut::kXYZ }) { | 
 |             unsupportedCs.push_back(SkColorSpace::MakeRGB(SkNamedTransferFn::k2Dot2, gamut)); | 
 |         } | 
 |  | 
 |         for (auto gamut : { SkNamedGamut::kAdobeRGB, SkNamedGamut::kDisplayP3, | 
 |                             SkNamedGamut::kXYZ }) { | 
 |             unsupportedCs.push_back(SkColorSpace::MakeRGB(SkNamedTransferFn::kRec2020, gamut)); | 
 |         } | 
 |  | 
 |         for (auto gamut : { SkNamedGamut::kAdobeRGB, SkNamedGamut::kDisplayP3, | 
 |                             SkNamedGamut::kRec2020, SkNamedGamut::kXYZ }) { | 
 |             unsupportedCs.push_back(SkColorSpace::MakeRGB(SkNamedTransferFn::kLinear, gamut)); | 
 |         } | 
 |  | 
 |         for (auto gamut : { SkNamedGamut::kAdobeRGB, | 
 |                             SkNamedGamut::kRec2020, SkNamedGamut::kXYZ }) { | 
 |             unsupportedCs.push_back(SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, gamut)); | 
 |         } | 
 |  | 
 |         for (auto fn : { SkNamedTransferFn::kSRGB, SkNamedTransferFn::k2Dot2, | 
 |                          SkNamedTransferFn::kLinear, SkNamedTransferFn::kRec2020 }) { | 
 |             unsupportedCs.push_back(SkColorSpace::MakeRGB(fn, kDCIP3)); | 
 |         } | 
 |  | 
 |         for (auto unsupported : unsupportedCs) { | 
 |             auto info = gen->getInfo().makeColorSpace(unsupported); | 
 |  | 
 |             SkBitmap bm; | 
 |             bm.allocPixels(info); | 
 |             REPORTER_ASSERT(r, !gen->getPixels(bm.pixmap())); | 
 |         } | 
 |     } | 
 | } | 
 |  | 
 | DEF_TEST(NdkDecode_reuseNoColorSpace, r) { | 
 |     static const struct { | 
 |         const char*         fPath; | 
 |         sk_sp<SkColorSpace> fCorrectedColorSpace; | 
 |         bool                fIsOpaque; | 
 |     } recs[] = { | 
 |         // AImageDecoder defaults to ADATASPACE_UNKNOWN for this image. | 
 |         {"images/wide_gamut_yellow_224_224_64.jpeg", SkColorSpace::MakeSRGB(), true}, | 
 |         // This image is SRGB, so convert to a different color space. | 
 |         {"images/example_1.png", SkColorSpace::MakeRGB(SkNamedTransferFn::k2Dot2, | 
 |                                                        SkNamedGamut::kAdobeRGB), false}, | 
 |     }; | 
 |     for (auto& rec : recs) { | 
 |         auto gen = make_generator(rec.fPath, r); | 
 |         if (!gen) continue; | 
 |  | 
 |         REPORTER_ASSERT(r, gen->getInfo().colorSpace()->isSRGB()); | 
 |         REPORTER_ASSERT(r, gen->getInfo().isOpaque() == rec.fIsOpaque); | 
 |  | 
 |         auto noColorCorrection = gen->getInfo().makeColorSpace(nullptr); | 
 |         if (rec.fIsOpaque) { | 
 |             // Use something other than the default color type to verify that the modified color | 
 |             // type is used even when the color space is reset. | 
 |             noColorCorrection = noColorCorrection.makeColorType(kRGB_565_SkColorType); | 
 |         } | 
 |  | 
 |         SkBitmap orig; | 
 |         orig.allocPixels(noColorCorrection); | 
 |         REPORTER_ASSERT(r, gen->getPixels(orig.pixmap())); | 
 |  | 
 |         SkBitmap corrected; | 
 |         corrected.allocPixels(noColorCorrection.makeColorSpace(rec.fCorrectedColorSpace)); | 
 |         REPORTER_ASSERT(r, gen->getPixels(corrected.pixmap())); | 
 |  | 
 |         REPORTER_ASSERT(r, !ToolUtils::equal_pixels(orig, corrected)); | 
 |  | 
 |         SkBitmap reuse; | 
 |         reuse.allocPixels(noColorCorrection); | 
 |         REPORTER_ASSERT(r, gen->getPixels(reuse.pixmap())); | 
 |  | 
 |         REPORTER_ASSERT(r, ToolUtils::equal_pixels(orig, reuse)); | 
 |     } | 
 | } | 
 |  | 
 | // The NDK supports scaling up to arbitrary dimensions. Skia forces clients to do this in a | 
 | // separate step, so the client is in charge of how to do the upscale. | 
 | DEF_TEST(NdkDecode_noUpscale, r) { | 
 |     for (const char* path: { | 
 |         "images/CMYK.jpg", | 
 |         "images/arrow.png", | 
 |         "images/baby_tux.webp", | 
 |         "images/color_wheel.gif", | 
 |         "images/rle.bmp", | 
 |         "images/color_wheel.ico", | 
 |         "images/google_chrome.ico", | 
 |         "images/mandrill.wbmp", | 
 |     }) { | 
 |         auto gen = make_generator(path, r); | 
 |         if (!gen) continue; | 
 |  | 
 |         const auto actualDimensions = gen->getInfo().dimensions(); | 
 |         const int width = actualDimensions.width(); | 
 |         const int height = actualDimensions.height(); | 
 |         for (SkISize dims : { | 
 |             SkISize{width*2, height*2}, | 
 |             SkISize{width + 1, height + 1}, | 
 |         }) { | 
 |             auto info = gen->getInfo().makeDimensions(dims); | 
 |             SkBitmap bm; | 
 |             bm.allocPixels(info); | 
 |             REPORTER_ASSERT(r, !gen->getPixels(bm.pixmap())); | 
 |         } | 
 |     } | 
 | } | 
 |  | 
 | // libwebp supports downscaling to an arbitrary scale factor, and this is supported by the NDK. | 
 | DEF_TEST(NdkDecode_webpArbitraryDownscale, r) { | 
 |     for (const char* path: { | 
 |         "images/baby_tux.webp", | 
 |         "images/yellow_rose.webp", | 
 |         "images/webp-color-profile-lossless.webp", | 
 |     }) { | 
 |         auto gen = make_generator(path, r); | 
 |         if (!gen) continue; | 
 |  | 
 |         const auto actualDimensions = gen->getInfo().dimensions(); | 
 |         const int width = actualDimensions.width(); | 
 |         const int height = actualDimensions.height(); | 
 |         for (SkISize dims : { | 
 |             SkISize{width/2, height/2}, | 
 |             SkISize{width/4, height/4}, | 
 |             SkISize{width/7, height/7}, | 
 |             SkISize{width - 1, height - 1}, | 
 |             SkISize{1, 1}, | 
 |             SkISize{5, 20} | 
 |         }) { | 
 |             auto info = gen->getInfo().makeDimensions(dims); | 
 |             SkBitmap bm; | 
 |             bm.allocPixels(info); | 
 |             REPORTER_ASSERT(r, gen->getPixels(bm.pixmap())); | 
 |  | 
 |             REPORTER_ASSERT(r, info.alphaType() != kUnpremul_SkAlphaType); | 
 |             auto unpremulInfo = info.makeAlphaType(kUnpremul_SkAlphaType); | 
 |             bm.allocPixels(unpremulInfo); | 
 |             REPORTER_ASSERT(r, gen->getPixels(bm.pixmap())); | 
 |         } | 
 |     } | 
 | } | 
 |  | 
 | // libjpeg-turbo supports downscaling to some scale factors. | 
 | DEF_TEST(NdkDecode_jpegDownscale, r) { | 
 |     static const struct { | 
 |         const char* fPath; | 
 |         SkISize     fSupportedSizes[4]; | 
 |     } recs[] = { | 
 |         {"images/CMYK.jpg", {{642,516},{321,258},{161,129},{81,65}}}, | 
 |         {"images/dog.jpg", {{180,180},{90,90},{45,45},{23,23}}}, | 
 |         {"images/grayscale.jpg", {{128,128},{64,64},{32,32},{16,16}}}, | 
 |         {"images/brickwork-texture.jpg", {{512,512},{256,256},{128,128},{64,64}}}, | 
 |         {"images/mandrill_h2v1.jpg", {{512,512},{256,256},{128,128},{64,64}}}, | 
 |         {"images/ducky.jpg", {{489,537},{245,269},{123,135},{62,68}}}, | 
 |     }; | 
 |     for (auto& rec : recs) { | 
 |         auto gen = make_generator(rec.fPath, r); | 
 |         if (!gen) continue; | 
 |  | 
 |         for (SkISize dims : rec.fSupportedSizes) { | 
 |             auto info = gen->getInfo().makeDimensions(dims); | 
 |             SkBitmap bm; | 
 |             bm.allocPixels(info); | 
 |             if (!gen->getPixels(bm.pixmap())) { | 
 |                 ERRORF(r, "failed to decode %s to {%i,%i}\n", rec.fPath, dims.width(), | 
 |                           dims.height()); | 
 |             } | 
 |  | 
 |             REPORTER_ASSERT(r, info.alphaType() != kUnpremul_SkAlphaType); | 
 |             auto unpremulInfo = info.makeAlphaType(kUnpremul_SkAlphaType); | 
 |             bm.allocPixels(unpremulInfo); | 
 |             REPORTER_ASSERT(r, gen->getPixels(bm.pixmap())); | 
 |         } | 
 |     } | 
 | } | 
 |  | 
 | DEF_TEST(NdkDecode_reuseJpeg, r) { | 
 |     auto gen = make_generator("images/CMYK.jpg", r); | 
 |     if (!gen) return; | 
 |  | 
 |     SkImageInfo info = gen->getInfo(); | 
 |     SkBitmap orig; | 
 |     orig.allocPixels(info); | 
 |     REPORTER_ASSERT(r, gen->getPixels(orig.pixmap())); | 
 |  | 
 |     info = info.makeWH(321, 258); | 
 |     SkBitmap downscaled; | 
 |     downscaled.allocPixels(info); | 
 |     REPORTER_ASSERT(r, gen->getPixels(downscaled.pixmap())); | 
 |  | 
 |     SkBitmap reuse; | 
 |     reuse.allocPixels(gen->getInfo()); | 
 |     REPORTER_ASSERT(r, gen->getPixels(reuse.pixmap())); | 
 |  | 
 |     REPORTER_ASSERT(r, ToolUtils::equal_pixels(orig, reuse)); | 
 | } | 
 |  | 
 | // The NDK supports scaling down to arbitrary dimensions. Skia forces clients to do this in a | 
 | // separate step, so the client is in charge of how to do the downscale. | 
 | DEF_TEST(NdkDecode_noDownscale, r) { | 
 |     for (const char* path: { | 
 |         "images/arrow.png", | 
 |         "images/color_wheel.gif", | 
 |         "images/rle.bmp", | 
 |         "images/color_wheel.ico", | 
 |         "images/google_chrome.ico", | 
 |         "images/mandrill.wbmp", | 
 |     }) { | 
 |         auto gen = make_generator(path, r); | 
 |         if (!gen) continue; | 
 |  | 
 |         const auto actualDimensions = gen->getInfo().dimensions(); | 
 |         const int width = actualDimensions.width(); | 
 |         const int height = actualDimensions.height(); | 
 |         for (SkISize dims : { | 
 |             SkISize{width/2, height/2}, | 
 |             SkISize{width/3, height/3}, | 
 |             SkISize{width/4, height/4}, | 
 |             SkISize{width/8, height/8}, | 
 |             SkISize{width - 1, height - 1}, | 
 |         }) { | 
 |             auto info = gen->getInfo().makeDimensions(dims); | 
 |             SkBitmap bm; | 
 |             bm.allocPixels(info); | 
 |             REPORTER_ASSERT(r, !gen->getPixels(bm.pixmap())); | 
 |         } | 
 |     } | 
 | } | 
 |  | 
 | DEF_TEST(NdkDecode_Gray8, r) { | 
 |     static const struct { | 
 |         const char* fPath; | 
 |         bool        fGrayscale; | 
 |     } recs[] = { | 
 |         {"images/CMYK.jpg", false}, | 
 |         {"images/arrow.png", false}, | 
 |         {"images/baby_tux.webp", false}, | 
 |         {"images/color_wheel.gif", false}, | 
 |         {"images/rle.bmp", false}, | 
 |         {"images/color_wheel.ico", false}, | 
 |         {"images/google_chrome.ico", false}, | 
 |         {"images/mandrill.wbmp", true}, | 
 |         {"images/grayscale.jpg", true}, | 
 |         {"images/grayscale.png", true}, | 
 |     }; | 
 |     for (auto& rec : recs) { | 
 |         auto gen = make_generator(rec.fPath, r); | 
 |         if (!gen) continue; | 
 |  | 
 |         SkImageInfo info = gen->getInfo(); | 
 |         if (rec.fGrayscale) { | 
 |             REPORTER_ASSERT(r, info.colorType() == kGray_8_SkColorType); | 
 |             REPORTER_ASSERT(r, info.alphaType() == kOpaque_SkAlphaType); | 
 |         } else { | 
 |             info = info.makeColorType(kGray_8_SkColorType); | 
 |         } | 
 |         SkBitmap bm; | 
 |         bm.allocPixels(info); | 
 |         bool success = gen->getPixels(bm.pixmap()); | 
 |         if (success != rec.fGrayscale) { | 
 |             ERRORF(r, "Expected decoding %s to Gray8 to %s. Actual: %s\n", rec.fPath, | 
 |                       (rec.fGrayscale ? "succeed" : "fail"), (success ? "succeed" : "fail")); | 
 |         } | 
 |     } | 
 | } | 
 |  | 
 | DEF_TEST(NdkDecode_Opaque_and_565, r) { | 
 |     for (const char* path: { | 
 |         "images/CMYK.jpg", | 
 |         "images/dog.jpg", | 
 |         "images/ducky.jpg", | 
 |         "images/arrow.png", | 
 |         "images/example_1.png", | 
 |         "images/explosion_sprites.png", | 
 |         "images/lut_identity.png", | 
 |         "images/grayscale.png", | 
 |         "images/baby_tux.webp", | 
 |         "images/yellow_rose.webp", | 
 |         "images/webp-color-profile-lossless.webp", | 
 |         "images/colorTables.gif", | 
 |         "images/color_wheel.gif", | 
 |         "images/flightAnim.gif", | 
 |         "images/randPixels.gif", | 
 |         "images/rle.bmp", | 
 |         "images/color_wheel.ico", | 
 |         "images/google_chrome.ico", | 
 |         "images/mandrill.wbmp", | 
 |     }) { | 
 |         auto gen = make_generator(path, r); | 
 |         if (!gen) continue; | 
 |  | 
 |         auto info = gen->getInfo().makeAlphaType(kOpaque_SkAlphaType); | 
 |         SkBitmap bm; | 
 |         bm.allocPixels(info); | 
 |         bool success = gen->getPixels(bm.pixmap()); | 
 |         REPORTER_ASSERT(r, success == gen->getInfo().isOpaque()); | 
 |  | 
 |         info = info.makeColorType(kRGB_565_SkColorType); | 
 |         bm.allocPixels(info); | 
 |         success = gen->getPixels(bm.pixmap()); | 
 |         REPORTER_ASSERT(r, success == gen->getInfo().isOpaque()); | 
 |     } | 
 | } | 
 |  | 
 | DEF_TEST(NdkDecode_AlwaysSupportedColorTypes, r) { | 
 |     for (const char* path: { | 
 |         "images/CMYK.jpg", | 
 |         "images/dog.jpg", | 
 |         "images/ducky.jpg", | 
 |         "images/arrow.png", | 
 |         "images/example_1.png", | 
 |         "images/explosion_sprites.png", | 
 |         "images/lut_identity.png", | 
 |         "images/grayscale.png", | 
 |         "images/baby_tux.webp", | 
 |         "images/yellow_rose.webp", | 
 |         "images/webp-color-profile-lossless.webp", | 
 |         "images/colorTables.gif", | 
 |         "images/color_wheel.gif", | 
 |         "images/flightAnim.gif", | 
 |         "images/randPixels.gif", | 
 |         "images/rle.bmp", | 
 |         "images/color_wheel.ico", | 
 |         "images/google_chrome.ico", | 
 |         "images/mandrill.wbmp", | 
 |     }) { | 
 |         auto gen = make_generator(path, r); | 
 |         if (!gen) continue; | 
 |  | 
 |         auto info = gen->getInfo().makeColorType(kRGBA_F16_SkColorType); | 
 |         SkBitmap bm; | 
 |         bm.allocPixels(info); | 
 |         REPORTER_ASSERT(r, gen->getPixels(bm.pixmap())); | 
 |  | 
 |         // This also tests that we can reuse the same generator for a different | 
 |         // color type. | 
 |         info = info.makeColorType(kRGBA_8888_SkColorType); | 
 |         bm.allocPixels(info); | 
 |         REPORTER_ASSERT(r, gen->getPixels(bm.pixmap())); | 
 |     } | 
 | } | 
 |  | 
 | DEF_TEST(NdkDecode_UnsupportedColorTypes, r) { | 
 |     for (const char* path: { | 
 |         "images/CMYK.jpg", | 
 |         "images/dog.jpg", | 
 |         "images/ducky.jpg", | 
 |         "images/arrow.png", | 
 |         "images/example_1.png", | 
 |         "images/explosion_sprites.png", | 
 |         "images/lut_identity.png", | 
 |         "images/grayscale.png", | 
 |         "images/baby_tux.webp", | 
 |         "images/yellow_rose.webp", | 
 |         "images/webp-color-profile-lossless.webp", | 
 |         "images/colorTables.gif", | 
 |         "images/color_wheel.gif", | 
 |         "images/flightAnim.gif", | 
 |         "images/randPixels.gif", | 
 |         "images/rle.bmp", | 
 |         "images/color_wheel.ico", | 
 |         "images/google_chrome.ico", | 
 |         "images/mandrill.wbmp", | 
 |     }) { | 
 |         auto gen = make_generator(path, r); | 
 |         if (!gen) continue; | 
 |  | 
 |         for (SkColorType ct : { | 
 |             kUnknown_SkColorType, | 
 |             kAlpha_8_SkColorType, | 
 |             kARGB_4444_SkColorType, | 
 |             kRGB_888x_SkColorType, | 
 |             kBGRA_8888_SkColorType, | 
 |             kRGBA_1010102_SkColorType, | 
 |             kBGRA_1010102_SkColorType, | 
 |             kRGB_101010x_SkColorType, | 
 |             kBGR_101010x_SkColorType, | 
 |             kRGBA_F16Norm_SkColorType, | 
 |             kRGBA_F32_SkColorType, | 
 |             kR8G8_unorm_SkColorType, | 
 |             kA16_float_SkColorType, | 
 |             kR16G16_float_SkColorType, | 
 |             kA16_unorm_SkColorType, | 
 |             kR16G16_unorm_SkColorType, | 
 |             kR16G16B16A16_unorm_SkColorType, | 
 |         }) { | 
 |             auto info = gen->getInfo().makeColorType(ct); | 
 |             SkBitmap bm; | 
 |             bm.allocPixels(info); | 
 |             if (gen->getPixels(bm.pixmap())) { | 
 |                 ERRORF(r, "Expected decoding %s to %i to fail!", path, ct); | 
 |             } | 
 |         } | 
 |     } | 
 | } | 
 | #endif // SK_ENABLE_NDK_IMAGES |