1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
|
/*
* Copyright 2015 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "SkSwizzle.h"
#include "SkSwizzler.h"
#include "Test.h"
#include "SkOpts.h"
// These are the values that we will look for to indicate that the fill was successful
static const uint8_t kFillIndex = 0x11;
static const uint8_t kFillGray = 0x22;
static const uint16_t kFill565 = 0x3344;
static const uint32_t kFillColor = 0x55667788;
static void check_fill(skiatest::Reporter* r,
const SkImageInfo& imageInfo,
uint32_t startRow,
uint32_t endRow,
size_t rowBytes,
uint32_t offset,
uint32_t colorOrIndex) {
// Calculate the total size of the image in bytes. Use the smallest possible size.
// The offset value tells us to adjust the pointer from the memory we allocate in order
// to test on different memory alignments. If offset is nonzero, we need to increase the
// size of the memory we allocate in order to make sure that we have enough. We are
// still allocating the smallest possible size.
const size_t totalBytes = imageInfo.getSafeSize(rowBytes) + offset;
// Create fake image data where every byte has a value of 0
std::unique_ptr<uint8_t[]> storage(new uint8_t[totalBytes]);
memset(storage.get(), 0, totalBytes);
// Adjust the pointer in order to test on different memory alignments
uint8_t* imageData = storage.get() + offset;
uint8_t* imageStart = imageData + rowBytes * startRow;
const SkImageInfo fillInfo = imageInfo.makeWH(imageInfo.width(), endRow - startRow + 1);
SkSampler::Fill(fillInfo, imageStart, rowBytes, colorOrIndex, SkCodec::kNo_ZeroInitialized);
// Ensure that the pixels are filled properly
// The bots should catch any memory corruption
uint8_t* indexPtr = imageData + startRow * rowBytes;
uint8_t* grayPtr = indexPtr;
uint32_t* colorPtr = (uint32_t*) indexPtr;
uint16_t* color565Ptr = (uint16_t*) indexPtr;
for (uint32_t y = startRow; y <= endRow; y++) {
for (int32_t x = 0; x < imageInfo.width(); x++) {
switch (imageInfo.colorType()) {
case kIndex_8_SkColorType:
REPORTER_ASSERT(r, kFillIndex == indexPtr[x]);
break;
case kN32_SkColorType:
REPORTER_ASSERT(r, kFillColor == colorPtr[x]);
break;
case kGray_8_SkColorType:
REPORTER_ASSERT(r, kFillGray == grayPtr[x]);
break;
case kRGB_565_SkColorType:
REPORTER_ASSERT(r, kFill565 == color565Ptr[x]);
break;
default:
REPORTER_ASSERT(r, false);
break;
}
}
indexPtr += rowBytes;
colorPtr = (uint32_t*) indexPtr;
}
}
// Test Fill() with different combinations of dimensions, alignment, and padding
DEF_TEST(SwizzlerFill, r) {
// Test on an invalid width and representative widths
const uint32_t widths[] = { 0, 10, 50 };
// In order to call Fill(), there must be at least one row to fill
// Test on the smallest possible height and representative heights
const uint32_t heights[] = { 1, 5, 10 };
// Test on interesting possibilities for row padding
const uint32_t paddings[] = { 0, 4 };
// Iterate over test dimensions
for (uint32_t width : widths) {
for (uint32_t height : heights) {
// Create image info objects
const SkImageInfo colorInfo = SkImageInfo::MakeN32(width, height, kUnknown_SkAlphaType);
const SkImageInfo grayInfo = colorInfo.makeColorType(kGray_8_SkColorType);
const SkImageInfo indexInfo = colorInfo.makeColorType(kIndex_8_SkColorType);
const SkImageInfo color565Info = colorInfo.makeColorType(kRGB_565_SkColorType);
for (uint32_t padding : paddings) {
// Calculate row bytes
const size_t colorRowBytes = SkColorTypeBytesPerPixel(kN32_SkColorType) * width
+ padding;
const size_t indexRowBytes = width + padding;
const size_t grayRowBytes = indexRowBytes;
const size_t color565RowBytes =
SkColorTypeBytesPerPixel(kRGB_565_SkColorType) * width + padding;
// If there is padding, we can invent an offset to change the memory alignment
for (uint32_t offset = 0; offset <= padding; offset += 4) {
// Test all possible start rows with all possible end rows
for (uint32_t startRow = 0; startRow < height; startRow++) {
for (uint32_t endRow = startRow; endRow < height; endRow++) {
// Test fill with each color type
check_fill(r, colorInfo, startRow, endRow, colorRowBytes, offset,
kFillColor);
check_fill(r, indexInfo, startRow, endRow, indexRowBytes, offset,
kFillIndex);
check_fill(r, grayInfo, startRow, endRow, grayRowBytes, offset,
kFillGray);
check_fill(r, color565Info, startRow, endRow, color565RowBytes, offset,
kFill565);
}
}
}
}
}
}
}
DEF_TEST(SwizzleOpts, r) {
uint32_t dst, src;
// forall c, c*255 == c, c*0 == 0
for (int c = 0; c <= 255; c++) {
src = (255<<24) | c;
SkOpts::RGBA_to_rgbA(&dst, &src, 1);
REPORTER_ASSERT(r, dst == src);
SkOpts::RGBA_to_bgrA(&dst, &src, 1);
REPORTER_ASSERT(r, dst == (uint32_t)((255<<24) | (c<<16)));
src = (0<<24) | c;
SkOpts::RGBA_to_rgbA(&dst, &src, 1);
REPORTER_ASSERT(r, dst == 0);
SkOpts::RGBA_to_bgrA(&dst, &src, 1);
REPORTER_ASSERT(r, dst == 0);
}
// check a totally arbitrary color
src = 0xFACEB004;
SkOpts::RGBA_to_rgbA(&dst, &src, 1);
REPORTER_ASSERT(r, dst == 0xFACAAD04);
// swap red and blue
SkOpts::RGBA_to_BGRA(&dst, &src, 1);
REPORTER_ASSERT(r, dst == 0xFA04B0CE);
// all together now
SkOpts::RGBA_to_bgrA(&dst, &src, 1);
REPORTER_ASSERT(r, dst == 0xFA04ADCA);
}
DEF_TEST(PublicSwizzleOpts, r) {
uint32_t dst, src;
// check a totally arbitrary color
src = 0xFACEB004;
SkSwapRB(&dst, &src, 1);
REPORTER_ASSERT(r, dst == 0xFA04B0CE);
}
|