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