OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2012 The Android Open Source Project | 2 * Copyright 2012 The Android Open Source Project |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 /** | 8 /** |
9 * Functions to transform scanlines between packed-pixel formats. | 9 * Functions to transform scanlines between packed-pixel formats. |
10 */ | 10 */ |
11 | 11 |
12 #include "SkBitmap.h" | 12 #include "SkBitmap.h" |
13 #include "SkColor.h" | 13 #include "SkColor.h" |
14 #include "SkColorPriv.h" | 14 #include "SkColorPriv.h" |
15 #include "SkPreConfig.h" | 15 #include "SkPreConfig.h" |
16 #include "SkUnPreMultiply.h" | 16 #include "SkUnPreMultiply.h" |
17 | 17 |
18 /** | 18 /** |
19 * Function template for transforming scanlines. | 19 * Function template for transforming scanlines. |
scroggo
2016/09/12 17:16:50
This should probably state what "bpp" means. I'm g
msarett
2016/09/12 19:39:20
Done. It is dst bytesPerPixel, though src would b
scroggo
2016/09/12 19:54:31
It looks like you pass the src's bytes per pixel.
msarett
2016/09/12 20:27:57
Done, thanks
| |
20 * Transform 'width' pixels from 'src' buffer into 'dst' buffer, | 20 * Transform 'width' pixels from 'src' buffer into 'dst' buffer, |
21 * repacking color channel data as appropriate for the given transformation. | 21 * repacking color channel data as appropriate for the given transformation. |
22 */ | 22 */ |
23 typedef void (*transform_scanline_proc)(const char* SK_RESTRICT src, | 23 typedef void (*transform_scanline_proc)(uint8_t* dst, const void* src, int width , int bpp); |
scroggo
2016/09/12 17:16:50
Just out of curiosity, why did you switch to uint8
msarett
2016/09/12 19:39:20
You're right, back to char and SK_RESTRICT.
| |
24 int width, char* SK_RESTRICT dst); | |
25 | 24 |
26 /** | 25 /** |
27 * Identity transformation: just copy bytes from src to dst. | 26 * Identity transformation: just copy bytes from src to dst. |
28 */ | 27 */ |
29 static void transform_scanline_memcpy(const char* SK_RESTRICT src, int width, | 28 static void transform_scanline_memcpy(uint8_t* dst, const void* src, int width, int bpp) { |
30 char* SK_RESTRICT dst) { | 29 memcpy(dst, src, width * bpp); |
31 memcpy(dst, src, width); | |
32 } | 30 } |
33 | 31 |
34 /** | 32 /** |
35 * Transform from kRGB_565_Config to 3-bytes-per-pixel RGB. | 33 * Transform from kRGB_565_Config to 3-bytes-per-pixel RGB. |
36 * Alpha channel data is not present in kRGB_565_Config format, so there is no | 34 * Alpha channel data is not present in kRGB_565_Config format, so there is no |
37 * alpha channel data to preserve. | 35 * alpha channel data to preserve. |
38 */ | 36 */ |
39 static void transform_scanline_565(const char* SK_RESTRICT src, int width, | 37 static void transform_scanline_565(uint8_t* dst, const void* src, int width, int ) { |
40 char* SK_RESTRICT dst) { | 38 const uint16_t* srcP = (const uint16_t*)src; |
41 const uint16_t* SK_RESTRICT srcP = (const uint16_t*)src; | |
42 for (int i = 0; i < width; i++) { | 39 for (int i = 0; i < width; i++) { |
43 unsigned c = *srcP++; | 40 unsigned c = *srcP++; |
44 *dst++ = SkPacked16ToR32(c); | 41 *dst++ = SkPacked16ToR32(c); |
45 *dst++ = SkPacked16ToG32(c); | 42 *dst++ = SkPacked16ToG32(c); |
46 *dst++ = SkPacked16ToB32(c); | 43 *dst++ = SkPacked16ToB32(c); |
47 } | 44 } |
48 } | 45 } |
49 | 46 |
50 /** | 47 /** |
51 * Transform from kARGB_8888_Config to 3-bytes-per-pixel RGB. | 48 * Transform from kRGBA_8888_SkColorType to 3-bytes-per-pixel RGB. |
52 * Alpha channel data, if any, is abandoned. | 49 * Alpha channel data is abandoned. |
53 */ | 50 */ |
54 static void transform_scanline_888(const char* SK_RESTRICT src, int width, | 51 static void transform_scanline_RGB1(uint8_t* dst, const void* src, int width, in t) { |
scroggo
2016/09/12 17:16:50
How'd you choose the "1" in the name? (I might be
msarett
2016/09/12 19:39:20
I think RGBX is a better name, switching.
| |
55 char* SK_RESTRICT dst) { | 52 const SkPMColor* srcP = (const SkPMColor*)src; |
56 const SkPMColor* SK_RESTRICT srcP = (const SkPMColor*)src; | |
57 for (int i = 0; i < width; i++) { | 53 for (int i = 0; i < width; i++) { |
58 SkPMColor c = *srcP++; | 54 SkPMColor c = *srcP++; |
59 *dst++ = SkGetPackedR32(c); | 55 *dst++ = (c >> 0) & 0xFF; |
60 *dst++ = SkGetPackedG32(c); | 56 *dst++ = (c >> 8) & 0xFF; |
61 *dst++ = SkGetPackedB32(c); | 57 *dst++ = (c >> 16) & 0xFF; |
62 } | 58 } |
63 } | 59 } |
64 | 60 |
61 /** | |
62 * Transform from kBGRA_8888_SkColorType to 3-bytes-per-pixel RGB. | |
63 * Alpha channel data is abandoned. | |
64 */ | |
65 static void transform_scanline_BGR1(uint8_t* dst, const void* src, int width, in t) { | |
66 const SkPMColor* srcP = (const SkPMColor*)src; | |
67 for (int i = 0; i < width; i++) { | |
68 SkPMColor c = *srcP++; | |
scroggo
2016/09/12 17:16:50
One of these uses of SkPMColor is a lie, but I sup
msarett
2016/09/12 19:39:20
Let's use uint32_t...
| |
69 *dst++ = (c >> 16) & 0xFF; | |
70 *dst++ = (c >> 8) & 0xFF; | |
71 *dst++ = (c >> 0) & 0xFF; | |
72 } | |
73 } | |
74 | |
65 /** | 75 /** |
66 * Transform from kARGB_4444_Config to 3-bytes-per-pixel RGB. | 76 * Transform from kARGB_4444_Config to 3-bytes-per-pixel RGB. |
67 * Alpha channel data, if any, is abandoned. | 77 * Alpha channel data, if any, is abandoned. |
68 */ | 78 */ |
69 static void transform_scanline_444(const char* SK_RESTRICT src, int width, | 79 static void transform_scanline_444(uint8_t* dst, const void* src, int width, int ) { |
70 char* SK_RESTRICT dst) { | 80 const SkPMColor16* srcP = (const SkPMColor16*)src; |
71 const SkPMColor16* SK_RESTRICT srcP = (const SkPMColor16*)src; | |
72 for (int i = 0; i < width; i++) { | 81 for (int i = 0; i < width; i++) { |
73 SkPMColor16 c = *srcP++; | 82 SkPMColor16 c = *srcP++; |
74 *dst++ = SkPacked4444ToR32(c); | 83 *dst++ = SkPacked4444ToR32(c); |
75 *dst++ = SkPacked4444ToG32(c); | 84 *dst++ = SkPacked4444ToG32(c); |
76 *dst++ = SkPacked4444ToB32(c); | 85 *dst++ = SkPacked4444ToB32(c); |
77 } | 86 } |
78 } | 87 } |
79 | 88 |
80 /** | 89 /** |
81 * Transform from kARGB_8888_Config to 4-bytes-per-pixel RGBA. | 90 * Transform from kPremul, kRGBA_8888_SkColorType to 4-bytes-per-pixel unpremult iplied RGBA. |
82 * (This would be the identity transformation, except for byte-order and | |
83 * scaling of RGB based on alpha channel). | |
84 */ | 91 */ |
85 static void transform_scanline_8888(const char* SK_RESTRICT src, int width, | 92 static void transform_scanline_rgbA(uint8_t* dst, const void* src, int width, in t) { |
86 char* SK_RESTRICT dst) { | 93 const SkPMColor* srcP = (const SkPMColor*)src; |
87 const SkPMColor* SK_RESTRICT srcP = (const SkPMColor*)src; | 94 const SkUnPreMultiply::Scale* table = SkUnPreMultiply::GetScaleTable(); |
88 const SkUnPreMultiply::Scale* SK_RESTRICT table = | |
89 SkUnPreMultiply::GetScaleTable(); | |
90 | 95 |
91 for (int i = 0; i < width; i++) { | 96 for (int i = 0; i < width; i++) { |
92 SkPMColor c = *srcP++; | 97 SkPMColor c = *srcP++; |
93 unsigned a = SkGetPackedA32(c); | 98 unsigned r = (c >> 0) & 0xFF; |
94 unsigned r = SkGetPackedR32(c); | 99 unsigned g = (c >> 8) & 0xFF; |
95 unsigned g = SkGetPackedG32(c); | 100 unsigned b = (c >> 16) & 0xFF; |
96 unsigned b = SkGetPackedB32(c); | 101 unsigned a = (c >> 24) & 0xFF; |
97 | 102 |
98 if (0 != a && 255 != a) { | 103 if (0 != a && 255 != a) { |
99 SkUnPreMultiply::Scale scale = table[a]; | 104 SkUnPreMultiply::Scale scale = table[a]; |
105 r = SkUnPreMultiply::ApplyScale(scale, r); | |
106 g = SkUnPreMultiply::ApplyScale(scale, g); | |
107 b = SkUnPreMultiply::ApplyScale(scale, b); | |
108 } | |
109 *dst++ = r; | |
110 *dst++ = g; | |
111 *dst++ = b; | |
112 *dst++ = a; | |
113 } | |
114 } | |
115 | |
116 /** | |
117 * Transform from kPremul, kBGRA_8888_SkColorType to 4-bytes-per-pixel unpremult iplied RGBA. | |
118 */ | |
119 static void transform_scanline_bgrA(uint8_t* dst, const void* src, int width, in t) { | |
120 const SkPMColor* srcP = (const SkPMColor*)src; | |
121 const SkUnPreMultiply::Scale* table = SkUnPreMultiply::GetScaleTable(); | |
122 | |
123 for (int i = 0; i < width; i++) { | |
124 SkPMColor c = *srcP++; | |
125 unsigned r = (c >> 16) & 0xFF; | |
scroggo
2016/09/12 17:16:50
Can we share code between these two methods (maybe
msarett
2016/09/12 19:39:20
SGTM
| |
126 unsigned g = (c >> 8) & 0xFF; | |
127 unsigned b = (c >> 0) & 0xFF; | |
128 unsigned a = (c >> 24) & 0xFF; | |
129 | |
130 if (0 != a && 255 != a) { | |
131 SkUnPreMultiply::Scale scale = table[a]; | |
100 r = SkUnPreMultiply::ApplyScale(scale, r); | 132 r = SkUnPreMultiply::ApplyScale(scale, r); |
101 g = SkUnPreMultiply::ApplyScale(scale, g); | 133 g = SkUnPreMultiply::ApplyScale(scale, g); |
102 b = SkUnPreMultiply::ApplyScale(scale, b); | 134 b = SkUnPreMultiply::ApplyScale(scale, b); |
103 } | 135 } |
104 *dst++ = r; | 136 *dst++ = r; |
105 *dst++ = g; | 137 *dst++ = g; |
106 *dst++ = b; | 138 *dst++ = b; |
107 *dst++ = a; | 139 *dst++ = a; |
108 } | 140 } |
109 } | 141 } |
110 | 142 |
111 /** | 143 /** |
144 * Transform from kUnpremul, kBGRA_8888_SkColorType to 4-bytes-per-pixel unpremu ltiplied RGBA. | |
145 */ | |
146 static void transform_scanline_BGRA(uint8_t* dst, const void* src, int width, in t) { | |
147 const SkPMColor* srcP = (const SkPMColor*)src; | |
148 for (int i = 0; i < width; i++) { | |
149 SkPMColor c = *srcP++; | |
150 *dst++ = (c >> 16) & 0xFF; | |
151 *dst++ = (c >> 8) & 0xFF; | |
152 *dst++ = (c >> 0) & 0xFF; | |
153 *dst++ = (c >> 24) & 0xFF; | |
154 } | |
155 } | |
156 | |
157 /** | |
112 * Transform from kARGB_8888_Config to 4-bytes-per-pixel RGBA, | 158 * Transform from kARGB_8888_Config to 4-bytes-per-pixel RGBA, |
113 * with scaling of RGB based on alpha channel. | 159 * with scaling of RGB based on alpha channel. |
114 */ | 160 */ |
115 static void transform_scanline_4444(const char* SK_RESTRICT src, int width, | 161 static void transform_scanline_4444(uint8_t* dst, const void* src, int width, in t) { |
116 char* SK_RESTRICT dst) { | 162 const SkPMColor16* srcP = (const SkPMColor16*)src; |
117 const SkPMColor16* SK_RESTRICT srcP = (const SkPMColor16*)src; | 163 const SkUnPreMultiply::Scale* table = SkUnPreMultiply::GetScaleTable(); |
118 const SkUnPreMultiply::Scale* SK_RESTRICT table = | |
119 SkUnPreMultiply::GetScaleTable(); | |
120 | 164 |
121 for (int i = 0; i < width; i++) { | 165 for (int i = 0; i < width; i++) { |
122 SkPMColor16 c = *srcP++; | 166 SkPMColor16 c = *srcP++; |
123 unsigned a = SkPacked4444ToA32(c); | 167 unsigned a = SkPacked4444ToA32(c); |
124 unsigned r = SkPacked4444ToR32(c); | 168 unsigned r = SkPacked4444ToR32(c); |
125 unsigned g = SkPacked4444ToG32(c); | 169 unsigned g = SkPacked4444ToG32(c); |
126 unsigned b = SkPacked4444ToB32(c); | 170 unsigned b = SkPacked4444ToB32(c); |
127 | 171 |
128 if (0 != a && 255 != a) { | 172 if (0 != a && 255 != a) { |
129 SkUnPreMultiply::Scale scale = table[a]; | 173 SkUnPreMultiply::Scale scale = table[a]; |
130 r = SkUnPreMultiply::ApplyScale(scale, r); | 174 r = SkUnPreMultiply::ApplyScale(scale, r); |
131 g = SkUnPreMultiply::ApplyScale(scale, g); | 175 g = SkUnPreMultiply::ApplyScale(scale, g); |
132 b = SkUnPreMultiply::ApplyScale(scale, b); | 176 b = SkUnPreMultiply::ApplyScale(scale, b); |
133 } | 177 } |
134 *dst++ = r; | 178 *dst++ = r; |
135 *dst++ = g; | 179 *dst++ = g; |
136 *dst++ = b; | 180 *dst++ = b; |
137 *dst++ = a; | 181 *dst++ = a; |
138 } | 182 } |
139 } | 183 } |
OLD | NEW |