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