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 "SkTypes.h" 9 #include "Resources.h" 10 #include "Test.h" 11 12 #if SK_SUPPORT_GPU 13 #include "GrContext.h" 14 #endif 15 #include "SkCanvas.h" 16 #include "SkColorSpace_Base.h" 17 #include "SkImage.h" 18 #include "SkSurface.h" 19 #include "SkReadBuffer.h" 20 #include "SkWriteBuffer.h" 21 22 static void test_flatten(skiatest::Reporter* reporter, const SkImageInfo& info) { 23 // Need a safe amount of 4-byte aligned storage. Note that one of the test ICC profiles 24 // is ~7500 bytes. 25 const size_t storageBytes = 8000; 26 SkAutoTMalloc<uint32_t> storage(storageBytes / sizeof(uint32_t)); 27 SkBinaryWriteBuffer wb(storage.get(), storageBytes); 28 info.flatten(wb); 29 SkASSERT(wb.bytesWritten() < storageBytes); 30 31 SkReadBuffer rb(storage.get(), wb.bytesWritten()); 32 33 // pick a noisy byte pattern, so we ensure that unflatten sets all of our fields 34 SkImageInfo info2 = SkImageInfo::Make(0xB8, 0xB8, (SkColorType) 0xB8, (SkAlphaType) 0xB8); 35 36 info2.unflatten(rb); 37 REPORTER_ASSERT(reporter, rb.offset() == wb.bytesWritten()); 38 39 REPORTER_ASSERT(reporter, info == info2); 40 } 41 42 DEF_TEST(ImageInfo_flattening, reporter) { 43 sk_sp<SkData> data = 44 SkData::MakeFromFileName(GetResourcePath("icc_profiles/HP_ZR30w.icc").c_str()); 45 sk_sp<SkColorSpace> space0 = SkColorSpace::MakeICC(data->data(), data->size()); 46 data = SkData::MakeFromFileName( GetResourcePath("icc_profiles/HP_Z32x.icc").c_str()); 47 sk_sp<SkColorSpace> space1 = SkColorSpace::MakeICC(data->data(), data->size()); 48 data = SkData::MakeFromFileName(GetResourcePath("icc_profiles/upperLeft.icc").c_str()); 49 sk_sp<SkColorSpace> space2 = SkColorSpace::MakeICC(data->data(), data->size()); 50 data = SkData::MakeFromFileName(GetResourcePath("icc_profiles/upperRight.icc").c_str()); 51 sk_sp<SkColorSpace> space3 = SkColorSpace::MakeICC(data->data(), data->size()); 52 53 sk_sp<SkColorSpace> spaces[] = { 54 nullptr, 55 SkColorSpace::MakeSRGB(), 56 SkColorSpace_Base::MakeNamed(SkColorSpace_Base::kAdobeRGB_Named), 57 space0, 58 space1, 59 space2, 60 space3, 61 }; 62 63 for (int ct = 0; ct <= kLastEnum_SkColorType; ++ct) { 64 for (int at = 0; at <= kLastEnum_SkAlphaType; ++at) { 65 for (auto& cs : spaces) { 66 SkImageInfo info = SkImageInfo::Make(100, 200, 67 static_cast<SkColorType>(ct), 68 static_cast<SkAlphaType>(at), 69 cs); 70 test_flatten(reporter, info); 71 } 72 } 73 } 74 } 75 76 static void check_isopaque(skiatest::Reporter* reporter, const sk_sp<SkSurface>& surface, 77 bool expectedOpaque) { 78 sk_sp<SkImage> image(surface->makeImageSnapshot()); 79 REPORTER_ASSERT(reporter, image->isOpaque() == expectedOpaque); 80 } 81 82 DEF_TEST(ImageIsOpaqueTest, reporter) { 83 SkImageInfo infoTransparent = SkImageInfo::MakeN32Premul(5, 5); 84 auto surfaceTransparent(SkSurface::MakeRaster(infoTransparent)); 85 check_isopaque(reporter, surfaceTransparent, false); 86 87 SkImageInfo infoOpaque = SkImageInfo::MakeN32(5, 5, kOpaque_SkAlphaType); 88 auto surfaceOpaque(SkSurface::MakeRaster(infoOpaque)); 89 check_isopaque(reporter, surfaceOpaque, true); 90 } 91 92 #if SK_SUPPORT_GPU 93 94 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ImageIsOpaqueTest_Gpu, reporter, ctxInfo) { 95 GrContext* context = ctxInfo.grContext(); 96 SkImageInfo infoTransparent = SkImageInfo::MakeN32Premul(5, 5); 97 auto surfaceTransparent(SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, infoTransparent)); 98 check_isopaque(reporter, surfaceTransparent, false); 99 100 SkImageInfo infoOpaque = SkImageInfo::MakeN32(5, 5, kOpaque_SkAlphaType); 101 auto surfaceOpaque(SkSurface::MakeRenderTarget(context,SkBudgeted::kNo, infoOpaque)); 102 103 check_isopaque(reporter, surfaceOpaque, true); 104 } 105 106 #endif 107 108 /////////////////////////////////////////////////////////////////////////////////////////////////// 109 #include "SkPictureRecorder.h" 110 111 static sk_sp<SkPicture> make_picture() { 112 SkPictureRecorder recorder; 113 SkCanvas* canvas = recorder.beginRecording({ 0, 0, 10, 10 }); 114 canvas->drawColor(SK_ColorRED); 115 return recorder.finishRecordingAsPicture(); 116 } 117 118 DEF_TEST(Image_isAlphaOnly, reporter) { 119 SkPMColor pmColors = 0; 120 SkPixmap pmap = { 121 SkImageInfo::MakeN32Premul(1, 1), 122 &pmColors, 123 sizeof(pmColors) 124 }; 125 for (auto& image : { 126 SkImage::MakeRasterCopy(pmap), 127 GetResourceAsImage("mandrill_128.png"), 128 GetResourceAsImage("color_wheel.jpg"), 129 SkImage::MakeFromPicture(make_picture(), { 10, 10 }, nullptr, nullptr, 130 SkImage::BitDepth::kU8, 131 SkColorSpace::MakeSRGB()), 132 }) 133 { 134 REPORTER_ASSERT(reporter, image->isAlphaOnly() == false); 135 } 136 137 REPORTER_ASSERT(reporter, SkImage::MakeRasterCopy({ 138 SkImageInfo::MakeA8(1, 1), (uint8_t*)&pmColors, 1})->isAlphaOnly() == true); 139 } 140