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