1 /*
2 * Copyright 2013 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 "SkBitmap.h"
9 #include "SkCanvas.h"
10 #include "SkColor.h"
11 #include "SkColorData.h"
12 #include "SkImage.h"
13 #include "SkImageGenerator.h"
14 #include "SkImageInfo.h"
15 #include "SkMakeUnique.h"
16 #include "SkRefCnt.h"
17 #include "SkTypes.h"
18 #include "SkUtils.h"
19 #include "Test.h"
20 #include "sk_tool_utils.h"
21
22 #include <utility>
23
24 class TestImageGenerator : public SkImageGenerator {
25 public:
26 enum TestType {
27 kFailGetPixels_TestType,
28 kSucceedGetPixels_TestType,
29 kLast_TestType = kSucceedGetPixels_TestType
30 };
Width()31 static int Width() { return 10; }
Height()32 static int Height() { return 10; }
33 // value choosen so that there is no loss when converting to to RGB565 and back
Color()34 static SkColor Color() { return sk_tool_utils::color_to_565(0xffaabbcc); }
PMColor()35 static SkPMColor PMColor() { return SkPreMultiplyColor(Color()); }
36
TestImageGenerator(TestType type,skiatest::Reporter * reporter,SkColorType colorType=kN32_SkColorType)37 TestImageGenerator(TestType type, skiatest::Reporter* reporter,
38 SkColorType colorType = kN32_SkColorType)
39 : INHERITED(GetMyInfo(colorType)), fType(type), fReporter(reporter) {
40 SkASSERT((fType <= kLast_TestType) && (fType >= 0));
41 }
~TestImageGenerator()42 ~TestImageGenerator() override {}
43
44 protected:
GetMyInfo(SkColorType colorType)45 static SkImageInfo GetMyInfo(SkColorType colorType) {
46 return SkImageInfo::Make(TestImageGenerator::Width(), TestImageGenerator::Height(),
47 colorType, kOpaque_SkAlphaType);
48 }
49
onGetPixels(const SkImageInfo & info,void * pixels,size_t rowBytes,const Options & options)50 bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
51 const Options& options) override {
52 REPORTER_ASSERT(fReporter, pixels != nullptr);
53 REPORTER_ASSERT(fReporter, rowBytes >= info.minRowBytes());
54 if (fType != kSucceedGetPixels_TestType) {
55 return false;
56 }
57 if (info.colorType() != kN32_SkColorType && info.colorType() != getInfo().colorType()) {
58 return false;
59 }
60 char* bytePtr = static_cast<char*>(pixels);
61 switch (info.colorType()) {
62 case kN32_SkColorType:
63 for (int y = 0; y < info.height(); ++y) {
64 sk_memset32((uint32_t*)bytePtr,
65 TestImageGenerator::PMColor(), info.width());
66 bytePtr += rowBytes;
67 }
68 break;
69 case kRGB_565_SkColorType:
70 for (int y = 0; y < info.height(); ++y) {
71 sk_memset16((uint16_t*)bytePtr,
72 SkPixel32ToPixel16(TestImageGenerator::PMColor()), info.width());
73 bytePtr += rowBytes;
74 }
75 break;
76 default:
77 return false;
78 }
79 return true;
80 }
81
82 private:
83 const TestType fType;
84 skiatest::Reporter* const fReporter;
85
86 typedef SkImageGenerator INHERITED;
87 };
88
89 ////////////////////////////////////////////////////////////////////////////////
90
DEF_TEST(Image_NewFromGenerator,r)91 DEF_TEST(Image_NewFromGenerator, r) {
92 const TestImageGenerator::TestType testTypes[] = {
93 TestImageGenerator::kFailGetPixels_TestType,
94 TestImageGenerator::kSucceedGetPixels_TestType,
95 };
96 const SkColorType testColorTypes[] = {
97 kN32_SkColorType,
98 kRGB_565_SkColorType
99 };
100 for (size_t i = 0; i < SK_ARRAY_COUNT(testTypes); ++i) {
101 TestImageGenerator::TestType test = testTypes[i];
102 for (const SkColorType testColorType : testColorTypes) {
103 auto gen = skstd::make_unique<TestImageGenerator>(test, r, testColorType);
104 sk_sp<SkImage> image(SkImage::MakeFromGenerator(std::move(gen)));
105 if (nullptr == image) {
106 ERRORF(r, "SkImage::NewFromGenerator unexpecedly failed ["
107 SK_SIZE_T_SPECIFIER "]", i);
108 continue;
109 }
110 REPORTER_ASSERT(r, TestImageGenerator::Width() == image->width());
111 REPORTER_ASSERT(r, TestImageGenerator::Height() == image->height());
112 REPORTER_ASSERT(r, image->isLazyGenerated());
113
114 SkBitmap bitmap;
115 bitmap.allocN32Pixels(TestImageGenerator::Width(), TestImageGenerator::Height());
116 SkCanvas canvas(bitmap);
117 const SkColor kDefaultColor = 0xffabcdef;
118 canvas.clear(kDefaultColor);
119 canvas.drawImage(image, 0, 0, nullptr);
120 if (TestImageGenerator::kSucceedGetPixels_TestType == test) {
121 REPORTER_ASSERT(
122 r, TestImageGenerator::Color() == bitmap.getColor(0, 0));
123 }
124 else {
125 REPORTER_ASSERT(r, kDefaultColor == bitmap.getColor(0, 0));
126 }
127 }
128 }
129 }
130