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 }; 31 static int Width() { return 10; } 32 static int Height() { return 10; } 33 // value choosen so that there is no loss when converting to to RGB565 and back 34 static SkColor Color() { return sk_tool_utils::color_to_565(0xffaabbcc); } 35 static SkPMColor PMColor() { return SkPreMultiplyColor(Color()); } 36 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 } 42 ~TestImageGenerator() override {} 43 44 protected: 45 static SkImageInfo GetMyInfo(SkColorType colorType) { 46 return SkImageInfo::Make(TestImageGenerator::Width(), TestImageGenerator::Height(), 47 colorType, kOpaque_SkAlphaType); 48 } 49 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 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