Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
SkMasks.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2015 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#include "src/core/SkMasks.h"
8
10
11/*
12 *
13 * Used to convert 1-7 bit color components into 8-bit color components
14 *
15 */
16static constexpr uint8_t n_bit_to_8_bit_lookup_table[] = {
17 // 1 bit
18 0, 255,
19 // 2 bits
20 0, 85, 170, 255,
21 // 3 bits
22 0, 36, 73, 109, 146, 182, 219, 255,
23 // 4 bits
24 0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255,
25 // 5 bits
26 0, 8, 16, 25, 33, 41, 49, 58, 66, 74, 82, 90, 99, 107, 115, 123, 132, 140,
27 148, 156, 165, 173, 181, 189, 197, 206, 214, 222, 230, 239, 247, 255,
28 // 6 bits
29 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 45, 49, 53, 57, 61, 65, 69, 73,
30 77, 81, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125, 130, 134, 138,
31 142, 146, 150, 154, 158, 162, 166, 170, 174, 178, 182, 186, 190, 194, 198,
32 202, 206, 210, 215, 219, 223, 227, 231, 235, 239, 243, 247, 251, 255,
33 // 7 bits
34 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38,
35 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76,
36 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110,
37 112, 114, 116, 118, 120, 122, 124, 126, 129, 131, 133, 135, 137, 139, 141,
38 143, 145, 147, 149, 151, 153, 155, 157, 159, 161, 163, 165, 167, 169, 171,
39 173, 175, 177, 179, 181, 183, 185, 187, 189, 191, 193, 195, 197, 199, 201,
40 203, 205, 207, 209, 211, 213, 215, 217, 219, 221, 223, 225, 227, 229, 231,
41 233, 235, 237, 239, 241, 243, 245, 247, 249, 251, 253, 255
42};
43
44/*
45 *
46 * Convert an n bit component to an 8-bit component
47 *
48 */
49static uint8_t convert_to_8(uint8_t component, uint32_t n) {
50 if (0 == n) {
51 return 0;
52 } else if (8 > n) {
53 return n_bit_to_8_bit_lookup_table[(1 << n) - 2 + component];
54 } else {
55 SkASSERT(8 == n);
56 return component;
57 }
58}
59
60static uint8_t get_comp(uint32_t pixel, uint32_t mask, uint32_t shift,
61 uint32_t size) {
62 return convert_to_8((pixel & mask) >> shift, size);
63}
64
65/*
66 *
67 * Get a color component
68 *
69 */
70uint8_t SkMasks::getRed(uint32_t pixel) const {
71 return get_comp(pixel, fRed.mask, fRed.shift, fRed.size);
72}
73uint8_t SkMasks::getGreen(uint32_t pixel) const {
74 return get_comp(pixel, fGreen.mask, fGreen.shift, fGreen.size);
75}
76uint8_t SkMasks::getBlue(uint32_t pixel) const {
77 return get_comp(pixel, fBlue.mask, fBlue.shift, fBlue.size);
78}
79uint8_t SkMasks::getAlpha(uint32_t pixel) const {
80 return get_comp(pixel, fAlpha.mask, fAlpha.shift, fAlpha.size);
81}
82
83/*
84 *
85 * Process an input mask to obtain the necessary information
86 *
87 */
88static SkMasks::MaskInfo process_mask(uint32_t mask) {
89 // Determine properties of the mask
90 uint32_t tempMask = mask;
91 uint32_t shift = 0;
92 uint32_t size = 0;
93 if (tempMask != 0) {
94 // Count trailing zeros on masks
95 for (; (tempMask & 1) == 0; tempMask >>= 1) {
96 shift++;
97 }
98 // Count the size of the mask
99 for (; tempMask & 1; tempMask >>= 1) {
100 size++;
101 }
102 // Verify that the mask is continuous
103 if (tempMask) {
104 SkDebugf("Warning: Bit mask is not continuous.\n");
105 // Finish processing the mask
106 for (; tempMask; tempMask >>= 1) {
107 size++;
108 }
109 }
110 // Truncate masks greater than 8 bits
111 if (size > 8) {
112 shift += size - 8;
113 size = 8;
114 mask &= 0xFF << shift;
115 }
116 }
117
118 return { mask, shift, size };
119}
120
121/*
122 *
123 * Create the masks object
124 *
125 */
126SkMasks* SkMasks::CreateMasks(InputMasks masks, int bytesPerPixel) {
127 SkASSERT(0 < bytesPerPixel && bytesPerPixel <= 4);
128
129 // Trim the input masks to match bytesPerPixel.
130 if (bytesPerPixel < 4) {
131 int bitsPerPixel = 8*bytesPerPixel;
132 masks.red &= (1 << bitsPerPixel) - 1;
133 masks.green &= (1 << bitsPerPixel) - 1;
134 masks.blue &= (1 << bitsPerPixel) - 1;
135 masks.alpha &= (1 << bitsPerPixel) - 1;
136 }
137
138 // Check that masks do not overlap.
139 if (((masks.red & masks.green) |
140 (masks.red & masks.blue ) |
141 (masks.red & masks.alpha) |
142 (masks.green & masks.blue ) |
143 (masks.green & masks.alpha) |
144 (masks.blue & masks.alpha) ) != 0) {
145 return nullptr;
146 }
147
148 return new SkMasks(process_mask(masks.red ),
149 process_mask(masks.green),
150 process_mask(masks.blue ),
151 process_mask(masks.alpha));
152}
153
#define SkASSERT(cond)
Definition SkAssert.h:116
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
static SkMasks::MaskInfo process_mask(uint32_t mask)
Definition SkMasks.cpp:88
static constexpr uint8_t n_bit_to_8_bit_lookup_table[]
Definition SkMasks.cpp:16
static uint8_t get_comp(uint32_t pixel, uint32_t mask, uint32_t shift, uint32_t size)
Definition SkMasks.cpp:60
static uint8_t convert_to_8(uint8_t component, uint32_t n)
Definition SkMasks.cpp:49
uint8_t getAlpha(uint32_t pixel) const
Definition SkMasks.cpp:79
static SkMasks * CreateMasks(InputMasks masks, int bytesPerPixel)
Definition SkMasks.cpp:126
uint8_t getBlue(uint32_t pixel) const
Definition SkMasks.cpp:76
uint8_t getGreen(uint32_t pixel) const
Definition SkMasks.cpp:73
uint8_t getRed(uint32_t pixel) const
Definition SkMasks.cpp:70
uint32_t mask
Definition SkMasks.h:18
uint32_t size
Definition SkMasks.h:20
uint32_t shift
Definition SkMasks.h:19