1 /*
2 * Copyright 2014 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 "include/core/SkAlphaType.h"
9 #include "include/core/SkCanvas.h"
10 #include "include/core/SkColor.h"
11 #include "include/core/SkColorSpace.h"
12 #include "include/core/SkColorType.h"
13 #include "include/core/SkData.h"
14 #include "include/core/SkGraphics.h"
15 #include "include/core/SkImage.h"
16 #include "include/core/SkImageGenerator.h"
17 #include "include/core/SkImageInfo.h"
18 #include "include/core/SkPicture.h"
19 #include "include/core/SkPictureRecorder.h"
20 #include "include/core/SkRefCnt.h"
21 #include "include/core/SkYUVAInfo.h"
22 #include "include/core/SkYUVAPixmaps.h"
23 #include "src/base/SkAutoMalloc.h"
24 #include "src/image/SkImageGeneratorPriv.h"
25 #include "tests/Test.h"
26
27 #include <memory>
28
29 #if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
30 #include "include/ports/SkImageGeneratorCG.h"
31 #elif defined(SK_BUILD_FOR_WIN)
32 #include "include/ports/SkImageGeneratorWIC.h"
33 #endif
34
35 static bool gMyFactoryWasCalled;
36
37 // NOLINTNEXTLINE(performance-unnecessary-value-param)
my_factory(sk_sp<SkData>)38 static std::unique_ptr<SkImageGenerator> my_factory(sk_sp<SkData>) {
39 gMyFactoryWasCalled = true;
40 return nullptr;
41 }
42
test_imagegenerator_factory(skiatest::Reporter * reporter)43 static void test_imagegenerator_factory(skiatest::Reporter* reporter) {
44 // just need a non-empty data to test things
45 sk_sp<SkData> data(SkData::MakeWithCString("test_imagegenerator_factory"));
46
47 gMyFactoryWasCalled = false;
48
49 REPORTER_ASSERT(reporter, !gMyFactoryWasCalled);
50
51 std::unique_ptr<SkImageGenerator> gen = SkImageGenerators::MakeFromEncoded(data);
52 REPORTER_ASSERT(reporter, nullptr == gen);
53 REPORTER_ASSERT(reporter, !gMyFactoryWasCalled);
54
55 // Test is racy, in that it hopes no other thread is changing this global...
56 auto prev = SkGraphics::SetImageGeneratorFromEncodedDataFactory(my_factory);
57 gen = SkImageGenerators::MakeFromEncoded(data);
58 REPORTER_ASSERT(reporter, nullptr == gen);
59 REPORTER_ASSERT(reporter, gMyFactoryWasCalled);
60
61 // This just verifies that the signatures match.
62 #if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
63 SkGraphics::SetImageGeneratorFromEncodedDataFactory(SkImageGeneratorCG::MakeFromEncodedCG);
64 #elif defined(SK_BUILD_FOR_WIN)
65 SkGraphics::SetImageGeneratorFromEncodedDataFactory(SkImageGeneratorWIC::MakeFromEncodedWIC);
66 #endif
67
68 SkGraphics::SetImageGeneratorFromEncodedDataFactory(prev);
69 }
70
71 class MyImageGenerator : public SkImageGenerator {
72 public:
MyImageGenerator()73 MyImageGenerator() : SkImageGenerator(SkImageInfo::MakeN32Premul(0, 0)) {}
74 };
75
DEF_TEST(ImageGenerator,reporter)76 DEF_TEST(ImageGenerator, reporter) {
77 MyImageGenerator ig;
78 SkYUVAPixmapInfo yuvaPixmapInfo;
79
80 // Check that the YUV decoding API does not cause any crashes
81 ig.queryYUVAInfo(SkYUVAPixmapInfo::SupportedDataTypes::All(), &yuvaPixmapInfo);
82 SkYUVAInfo yuvaInfo({250, 250},
83 SkYUVAInfo::PlaneConfig::kY_UV,
84 SkYUVAInfo::Subsampling::k420,
85 kJPEG_Full_SkYUVColorSpace);
86 yuvaPixmapInfo = SkYUVAPixmapInfo(yuvaInfo,
87 SkYUVAPixmapInfo::DataType::kUnorm8,
88 /*rowBytes[]*/ nullptr);
89 SkYUVAPixmaps yuvaPixmaps = SkYUVAPixmaps::Allocate(yuvaPixmapInfo);
90 ig.getYUVAPlanes(yuvaPixmaps);
91
92 // Suppressed due to https://code.google.com/p/skia/issues/detail?id=4339
93 if ((false)) {
94 test_imagegenerator_factory(reporter);
95 }
96 }
97
make_picture()98 static sk_sp<SkPicture> make_picture() {
99 SkPictureRecorder recorder;
100 recorder.beginRecording(100, 100)->drawColor(SK_ColorRED);
101 return recorder.finishRecordingAsPicture();
102 }
103
DEF_TEST(PictureImageGenerator,reporter)104 DEF_TEST(PictureImageGenerator, reporter) {
105 const struct {
106 SkColorType fColorType;
107 SkAlphaType fAlphaType;
108 } recs[] = {
109 { kRGBA_8888_SkColorType, kPremul_SkAlphaType },
110 { kBGRA_8888_SkColorType, kPremul_SkAlphaType },
111 { kRGBA_F16_SkColorType, kPremul_SkAlphaType },
112 { kRGBA_F32_SkColorType, kPremul_SkAlphaType },
113 { kRGBA_1010102_SkColorType, kPremul_SkAlphaType },
114
115 { kRGBA_8888_SkColorType, kUnpremul_SkAlphaType },
116 { kBGRA_8888_SkColorType, kUnpremul_SkAlphaType },
117 { kRGBA_F16_SkColorType, kUnpremul_SkAlphaType },
118 { kRGBA_F32_SkColorType, kUnpremul_SkAlphaType },
119 { kRGBA_1010102_SkColorType, kUnpremul_SkAlphaType },
120 };
121
122 auto colorspace = SkColorSpace::MakeSRGB();
123 auto picture = make_picture();
124 auto gen = SkImageGenerators::MakeFromPicture(
125 {100, 100}, picture, nullptr, nullptr, SkImages::BitDepth::kU8, colorspace);
126
127 // worst case for all requests
128 SkAutoMalloc storage(100 * 100 * SkColorTypeBytesPerPixel(kRGBA_F32_SkColorType));
129
130 for (const auto& rec : recs) {
131 SkImageInfo info = SkImageInfo::Make(100, 100, rec.fColorType, rec.fAlphaType, colorspace);
132 REPORTER_ASSERT(reporter, gen->getPixels(info, storage.get(), info.minRowBytes()));
133 }
134 }
135
136