blob: e10551cfe407fabc958466cac2fcd3a8f0c00961 [file] [log] [blame]
msarett74114382015-03-16 11:55:18 -07001/*
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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "include/core/SkTypes.h"
9#include "src/codec/SkCodecPriv.h"
10#include "src/codec/SkMasks.h"
msarett74114382015-03-16 11:55:18 -070011
12/*
13 *
14 * Used to convert 1-7 bit color components into 8-bit color components
15 *
16 */
Leon Scroggins III862c1962017-10-02 16:28:49 -040017static constexpr uint8_t n_bit_to_8_bit_lookup_table[] = {
msarett74114382015-03-16 11:55:18 -070018 // 1 bit
19 0, 255,
20 // 2 bits
21 0, 85, 170, 255,
22 // 3 bits
23 0, 36, 73, 109, 146, 182, 219, 255,
24 // 4 bits
25 0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255,
26 // 5 bits
27 0, 8, 16, 25, 33, 41, 49, 58, 66, 74, 82, 90, 99, 107, 115, 123, 132, 140,
28 148, 156, 165, 173, 181, 189, 197, 206, 214, 222, 230, 239, 247, 255,
29 // 6 bits
30 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 45, 49, 53, 57, 61, 65, 69, 73,
31 77, 81, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125, 130, 134, 138,
32 142, 146, 150, 154, 158, 162, 166, 170, 174, 178, 182, 186, 190, 194, 198,
33 202, 206, 210, 215, 219, 223, 227, 231, 235, 239, 243, 247, 251, 255,
34 // 7 bits
35 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38,
36 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76,
37 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110,
38 112, 114, 116, 118, 120, 122, 124, 126, 129, 131, 133, 135, 137, 139, 141,
39 143, 145, 147, 149, 151, 153, 155, 157, 159, 161, 163, 165, 167, 169, 171,
40 173, 175, 177, 179, 181, 183, 185, 187, 189, 191, 193, 195, 197, 199, 201,
41 203, 205, 207, 209, 211, 213, 215, 217, 219, 221, 223, 225, 227, 229, 231,
42 233, 235, 237, 239, 241, 243, 245, 247, 249, 251, 253, 255
43};
44
45/*
46 *
47 * Convert an n bit component to an 8-bit component
48 *
49 */
msarett02b407b2016-02-10 13:40:10 -080050static uint8_t convert_to_8(uint8_t component, uint32_t n) {
msarett74114382015-03-16 11:55:18 -070051 if (0 == n) {
52 return 0;
53 } else if (8 > n) {
54 return n_bit_to_8_bit_lookup_table[(1 << n) - 2 + component];
55 } else {
56 SkASSERT(8 == n);
57 return component;
58 }
59}
60
61static uint8_t get_comp(uint32_t pixel, uint32_t mask, uint32_t shift,
62 uint32_t size) {
63 return convert_to_8((pixel & mask) >> shift, size);
64}
65
66/*
67 *
68 * Get a color component
69 *
70 */
scroggo8b17dcb2015-09-30 12:26:49 -070071uint8_t SkMasks::getRed(uint32_t pixel) const {
msarett74114382015-03-16 11:55:18 -070072 return get_comp(pixel, fRed.mask, fRed.shift, fRed.size);
73}
scroggo8b17dcb2015-09-30 12:26:49 -070074uint8_t SkMasks::getGreen(uint32_t pixel) const {
msarett74114382015-03-16 11:55:18 -070075 return get_comp(pixel, fGreen.mask, fGreen.shift, fGreen.size);
76}
scroggo8b17dcb2015-09-30 12:26:49 -070077uint8_t SkMasks::getBlue(uint32_t pixel) const {
msarett74114382015-03-16 11:55:18 -070078 return get_comp(pixel, fBlue.mask, fBlue.shift, fBlue.size);
79}
scroggo8b17dcb2015-09-30 12:26:49 -070080uint8_t SkMasks::getAlpha(uint32_t pixel) const {
msarett74114382015-03-16 11:55:18 -070081 return get_comp(pixel, fAlpha.mask, fAlpha.shift, fAlpha.size);
82}
83
84/*
85 *
86 * Process an input mask to obtain the necessary information
87 *
88 */
Mike Klein65e84172019-02-13 12:25:55 -050089static const SkMasks::MaskInfo process_mask(uint32_t mask) {
msarett74114382015-03-16 11:55:18 -070090 // Determine properties of the mask
91 uint32_t tempMask = mask;
92 uint32_t shift = 0;
93 uint32_t size = 0;
94 if (tempMask != 0) {
95 // Count trailing zeros on masks
96 for (; (tempMask & 1) == 0; tempMask >>= 1) {
97 shift++;
98 }
99 // Count the size of the mask
100 for (; tempMask & 1; tempMask >>= 1) {
101 size++;
102 }
msarett02b407b2016-02-10 13:40:10 -0800103 // Verify that the mask is continuous
104 if (tempMask) {
105 SkCodecPrintf("Warning: Bit mask is not continuous.\n");
106 // Finish processing the mask
107 for (; tempMask; tempMask >>= 1) {
108 size++;
109 }
msarett74114382015-03-16 11:55:18 -0700110 }
111 // Truncate masks greater than 8 bits
112 if (size > 8) {
113 shift += size - 8;
114 size = 8;
msarett02b407b2016-02-10 13:40:10 -0800115 mask &= 0xFF << shift;
msarett74114382015-03-16 11:55:18 -0700116 }
117 }
118
Mike Klein65e84172019-02-13 12:25:55 -0500119 return { mask, shift, size };
msarett74114382015-03-16 11:55:18 -0700120}
121
122/*
123 *
124 * Create the masks object
125 *
126 */
Mike Klein65e84172019-02-13 12:25:55 -0500127SkMasks* SkMasks::CreateMasks(InputMasks masks, int bytesPerPixel) {
128 SkASSERT(0 < bytesPerPixel && bytesPerPixel <= 4);
129
130 // Trim the input masks to match bytesPerPixel.
131 if (bytesPerPixel < 4) {
132 int bitsPerPixel = 8*bytesPerPixel;
133 masks.red &= (1 << bitsPerPixel) - 1;
msarett74114382015-03-16 11:55:18 -0700134 masks.green &= (1 << bitsPerPixel) - 1;
Mike Klein65e84172019-02-13 12:25:55 -0500135 masks.blue &= (1 << bitsPerPixel) - 1;
msarett74114382015-03-16 11:55:18 -0700136 masks.alpha &= (1 << bitsPerPixel) - 1;
137 }
138
Mike Klein65e84172019-02-13 12:25:55 -0500139 // Check that masks do not overlap.
140 if (((masks.red & masks.green) |
141 (masks.red & masks.blue ) |
142 (masks.red & masks.alpha) |
143 (masks.green & masks.blue ) |
144 (masks.green & masks.alpha) |
145 (masks.blue & masks.alpha) ) != 0) {
halcanary96fcdcc2015-08-27 07:41:13 -0700146 return nullptr;
msarett74114382015-03-16 11:55:18 -0700147 }
148
Mike Klein65e84172019-02-13 12:25:55 -0500149 return new SkMasks(process_mask(masks.red ),
150 process_mask(masks.green),
151 process_mask(masks.blue ),
152 process_mask(masks.alpha));
msarett74114382015-03-16 11:55:18 -0700153}
154
155
scroggo8b17dcb2015-09-30 12:26:49 -0700156SkMasks::SkMasks(const MaskInfo& red, const MaskInfo& green,
157 const MaskInfo& blue, const MaskInfo& alpha)
msarett74114382015-03-16 11:55:18 -0700158 : fRed(red)
159 , fGreen(green)
160 , fBlue(blue)
161 , fAlpha(alpha)
162{}