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. |
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 * 'bpp' is bytes per pixel in the 'src' buffer. |
22 */ | 23 */ |
23 typedef void (*transform_scanline_proc)(const char* SK_RESTRICT src, | 24 typedef void (*transform_scanline_proc)(char* SK_RESTRICT dst, const char* SK_RE
STRICT src, |
24 int width, char* SK_RESTRICT dst); | 25 int width, int bpp); |
25 | 26 |
26 /** | 27 /** |
27 * Identity transformation: just copy bytes from src to dst. | 28 * Identity transformation: just copy bytes from src to dst. |
28 */ | 29 */ |
29 static void transform_scanline_memcpy(const char* SK_RESTRICT src, int width, | 30 static void transform_scanline_memcpy(char* SK_RESTRICT dst, const char* SK_REST
RICT src, |
30 char* SK_RESTRICT dst) { | 31 int width, int bpp) { |
31 memcpy(dst, src, width); | 32 memcpy(dst, src, width * bpp); |
32 } | 33 } |
33 | 34 |
34 /** | 35 /** |
35 * Transform from kRGB_565_Config to 3-bytes-per-pixel RGB. | 36 * 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 | 37 * Alpha channel data is not present in kRGB_565_Config format, so there is no |
37 * alpha channel data to preserve. | 38 * alpha channel data to preserve. |
38 */ | 39 */ |
39 static void transform_scanline_565(const char* SK_RESTRICT src, int width, | 40 static void transform_scanline_565(char* SK_RESTRICT dst, const char* SK_RESTRIC
T src, |
40 char* SK_RESTRICT dst) { | 41 int width, int) { |
41 const uint16_t* SK_RESTRICT srcP = (const uint16_t*)src; | 42 const uint16_t* srcP = (const uint16_t*)src; |
42 for (int i = 0; i < width; i++) { | 43 for (int i = 0; i < width; i++) { |
43 unsigned c = *srcP++; | 44 unsigned c = *srcP++; |
44 *dst++ = SkPacked16ToR32(c); | 45 *dst++ = SkPacked16ToR32(c); |
45 *dst++ = SkPacked16ToG32(c); | 46 *dst++ = SkPacked16ToG32(c); |
46 *dst++ = SkPacked16ToB32(c); | 47 *dst++ = SkPacked16ToB32(c); |
47 } | 48 } |
48 } | 49 } |
49 | 50 |
50 /** | 51 /** |
51 * Transform from kARGB_8888_Config to 3-bytes-per-pixel RGB. | 52 * Transform from kRGBA_8888_SkColorType to 3-bytes-per-pixel RGB. |
52 * Alpha channel data, if any, is abandoned. | 53 * Alpha channel data is abandoned. |
53 */ | 54 */ |
54 static void transform_scanline_888(const char* SK_RESTRICT src, int width, | 55 static void transform_scanline_RGBX(char* SK_RESTRICT dst, const char* SK_RESTRI
CT src, |
55 char* SK_RESTRICT dst) { | 56 int width, int) { |
56 const SkPMColor* SK_RESTRICT srcP = (const SkPMColor*)src; | 57 const uint32_t* srcP = (const SkPMColor*)src; |
57 for (int i = 0; i < width; i++) { | 58 for (int i = 0; i < width; i++) { |
58 SkPMColor c = *srcP++; | 59 uint32_t c = *srcP++; |
59 *dst++ = SkGetPackedR32(c); | 60 *dst++ = (c >> 0) & 0xFF; |
60 *dst++ = SkGetPackedG32(c); | 61 *dst++ = (c >> 8) & 0xFF; |
61 *dst++ = SkGetPackedB32(c); | 62 *dst++ = (c >> 16) & 0xFF; |
62 } | 63 } |
63 } | 64 } |
64 | 65 |
| 66 /** |
| 67 * Transform from kBGRA_8888_SkColorType to 3-bytes-per-pixel RGB. |
| 68 * Alpha channel data is abandoned. |
| 69 */ |
| 70 static void transform_scanline_BGRX(char* SK_RESTRICT dst, const char* SK_RESTRI
CT src, |
| 71 int width, int) { |
| 72 const uint32_t* srcP = (const SkPMColor*)src; |
| 73 for (int i = 0; i < width; i++) { |
| 74 uint32_t c = *srcP++; |
| 75 *dst++ = (c >> 16) & 0xFF; |
| 76 *dst++ = (c >> 8) & 0xFF; |
| 77 *dst++ = (c >> 0) & 0xFF; |
| 78 } |
| 79 } |
| 80 |
65 /** | 81 /** |
66 * Transform from kARGB_4444_Config to 3-bytes-per-pixel RGB. | 82 * Transform from kARGB_4444_Config to 3-bytes-per-pixel RGB. |
67 * Alpha channel data, if any, is abandoned. | 83 * Alpha channel data, if any, is abandoned. |
68 */ | 84 */ |
69 static void transform_scanline_444(const char* SK_RESTRICT src, int width, | 85 static void transform_scanline_444(char* SK_RESTRICT dst, const char* SK_RESTRIC
T src, |
70 char* SK_RESTRICT dst) { | 86 int width, int) { |
71 const SkPMColor16* SK_RESTRICT srcP = (const SkPMColor16*)src; | 87 const SkPMColor16* srcP = (const SkPMColor16*)src; |
72 for (int i = 0; i < width; i++) { | 88 for (int i = 0; i < width; i++) { |
73 SkPMColor16 c = *srcP++; | 89 SkPMColor16 c = *srcP++; |
74 *dst++ = SkPacked4444ToR32(c); | 90 *dst++ = SkPacked4444ToR32(c); |
75 *dst++ = SkPacked4444ToG32(c); | 91 *dst++ = SkPacked4444ToG32(c); |
76 *dst++ = SkPacked4444ToB32(c); | 92 *dst++ = SkPacked4444ToB32(c); |
77 } | 93 } |
78 } | 94 } |
79 | 95 |
80 /** | 96 template <bool kIsRGBA> |
81 * Transform from kARGB_8888_Config to 4-bytes-per-pixel RGBA. | 97 static inline void transform_scanline_unpremultiply(char* SK_RESTRICT dst, |
82 * (This would be the identity transformation, except for byte-order and | 98 const char* SK_RESTRICT src,
int width, int) { |
83 * scaling of RGB based on alpha channel). | 99 const uint32_t* srcP = (const SkPMColor*)src; |
84 */ | 100 const SkUnPreMultiply::Scale* table = SkUnPreMultiply::GetScaleTable(); |
85 static void transform_scanline_8888(const char* SK_RESTRICT src, int width, | |
86 char* SK_RESTRICT dst) { | |
87 const SkPMColor* SK_RESTRICT srcP = (const SkPMColor*)src; | |
88 const SkUnPreMultiply::Scale* SK_RESTRICT table = | |
89 SkUnPreMultiply::GetScaleTable(); | |
90 | 101 |
91 for (int i = 0; i < width; i++) { | 102 for (int i = 0; i < width; i++) { |
92 SkPMColor c = *srcP++; | 103 uint32_t c = *srcP++; |
93 unsigned a = SkGetPackedA32(c); | 104 unsigned r, g, b, a; |
94 unsigned r = SkGetPackedR32(c); | 105 if (kIsRGBA) { |
95 unsigned g = SkGetPackedG32(c); | 106 r = (c >> 0) & 0xFF; |
96 unsigned b = SkGetPackedB32(c); | 107 g = (c >> 8) & 0xFF; |
| 108 b = (c >> 16) & 0xFF; |
| 109 a = (c >> 24) & 0xFF; |
| 110 } else { |
| 111 r = (c >> 16) & 0xFF; |
| 112 g = (c >> 8) & 0xFF; |
| 113 b = (c >> 0) & 0xFF; |
| 114 a = (c >> 24) & 0xFF; |
| 115 } |
97 | 116 |
98 if (0 != a && 255 != a) { | 117 if (0 != a && 255 != a) { |
99 SkUnPreMultiply::Scale scale = table[a]; | 118 SkUnPreMultiply::Scale scale = table[a]; |
100 r = SkUnPreMultiply::ApplyScale(scale, r); | 119 r = SkUnPreMultiply::ApplyScale(scale, r); |
101 g = SkUnPreMultiply::ApplyScale(scale, g); | 120 g = SkUnPreMultiply::ApplyScale(scale, g); |
102 b = SkUnPreMultiply::ApplyScale(scale, b); | 121 b = SkUnPreMultiply::ApplyScale(scale, b); |
103 } | 122 } |
104 *dst++ = r; | 123 *dst++ = r; |
105 *dst++ = g; | 124 *dst++ = g; |
106 *dst++ = b; | 125 *dst++ = b; |
107 *dst++ = a; | 126 *dst++ = a; |
108 } | 127 } |
109 } | 128 } |
110 | 129 |
111 /** | 130 /** |
| 131 * Transform from kPremul, kRGBA_8888_SkColorType to 4-bytes-per-pixel unpremult
iplied RGBA. |
| 132 */ |
| 133 static void transform_scanline_rgbA(char* SK_RESTRICT dst, const char* SK_RESTRI
CT src, |
| 134 int width, int bpp) { |
| 135 transform_scanline_unpremultiply<true>(dst, src, width, bpp); |
| 136 } |
| 137 |
| 138 /** |
| 139 * Transform from kPremul, kBGRA_8888_SkColorType to 4-bytes-per-pixel unpremult
iplied RGBA. |
| 140 */ |
| 141 static void transform_scanline_bgrA(char* SK_RESTRICT dst, const char* SK_RESTRI
CT src, |
| 142 int width, int bpp) { |
| 143 transform_scanline_unpremultiply<false>(dst, src, width, bpp); |
| 144 } |
| 145 |
| 146 /** |
| 147 * Transform from kUnpremul, kBGRA_8888_SkColorType to 4-bytes-per-pixel unpremu
ltiplied RGBA. |
| 148 */ |
| 149 static void transform_scanline_BGRA(char* SK_RESTRICT dst, const char* SK_RESTRI
CT src, |
| 150 int width, int) { |
| 151 const uint32_t* srcP = (const SkPMColor*)src; |
| 152 for (int i = 0; i < width; i++) { |
| 153 uint32_t c = *srcP++; |
| 154 *dst++ = (c >> 16) & 0xFF; |
| 155 *dst++ = (c >> 8) & 0xFF; |
| 156 *dst++ = (c >> 0) & 0xFF; |
| 157 *dst++ = (c >> 24) & 0xFF; |
| 158 } |
| 159 } |
| 160 |
| 161 /** |
112 * Transform from kARGB_8888_Config to 4-bytes-per-pixel RGBA, | 162 * Transform from kARGB_8888_Config to 4-bytes-per-pixel RGBA, |
113 * with scaling of RGB based on alpha channel. | 163 * with scaling of RGB based on alpha channel. |
114 */ | 164 */ |
115 static void transform_scanline_4444(const char* SK_RESTRICT src, int width, | 165 static void transform_scanline_4444(char* SK_RESTRICT dst, const char* SK_RESTRI
CT src, |
116 char* SK_RESTRICT dst) { | 166 int width, int) { |
117 const SkPMColor16* SK_RESTRICT srcP = (const SkPMColor16*)src; | 167 const SkPMColor16* srcP = (const SkPMColor16*)src; |
118 const SkUnPreMultiply::Scale* SK_RESTRICT table = | 168 const SkUnPreMultiply::Scale* table = SkUnPreMultiply::GetScaleTable(); |
119 SkUnPreMultiply::GetScaleTable(); | |
120 | 169 |
121 for (int i = 0; i < width; i++) { | 170 for (int i = 0; i < width; i++) { |
122 SkPMColor16 c = *srcP++; | 171 SkPMColor16 c = *srcP++; |
123 unsigned a = SkPacked4444ToA32(c); | 172 unsigned a = SkPacked4444ToA32(c); |
124 unsigned r = SkPacked4444ToR32(c); | 173 unsigned r = SkPacked4444ToR32(c); |
125 unsigned g = SkPacked4444ToG32(c); | 174 unsigned g = SkPacked4444ToG32(c); |
126 unsigned b = SkPacked4444ToB32(c); | 175 unsigned b = SkPacked4444ToB32(c); |
127 | 176 |
128 if (0 != a && 255 != a) { | 177 if (0 != a && 255 != a) { |
129 SkUnPreMultiply::Scale scale = table[a]; | 178 SkUnPreMultiply::Scale scale = table[a]; |
130 r = SkUnPreMultiply::ApplyScale(scale, r); | 179 r = SkUnPreMultiply::ApplyScale(scale, r); |
131 g = SkUnPreMultiply::ApplyScale(scale, g); | 180 g = SkUnPreMultiply::ApplyScale(scale, g); |
132 b = SkUnPreMultiply::ApplyScale(scale, b); | 181 b = SkUnPreMultiply::ApplyScale(scale, b); |
133 } | 182 } |
134 *dst++ = r; | 183 *dst++ = r; |
135 *dst++ = g; | 184 *dst++ = g; |
136 *dst++ = b; | 185 *dst++ = b; |
137 *dst++ = a; | 186 *dst++ = a; |
138 } | 187 } |
139 } | 188 } |
OLD | NEW |