OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
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 #include "SkCodecPriv.h" | 8 #include "SkCodecPriv.h" |
9 #include "SkColorPriv.h" | 9 #include "SkColorPriv.h" |
10 #include "SkScaledCodec.h" | |
10 #include "SkSwizzler.h" | 11 #include "SkSwizzler.h" |
11 #include "SkTemplates.h" | 12 #include "SkTemplates.h" |
12 #include "SkUtils.h" | 13 #include "SkUtils.h" |
13 | 14 |
14 SkSwizzler::ResultAlpha SkSwizzler::GetResult(uint8_t zeroAlpha, | 15 SkSwizzler::ResultAlpha SkSwizzler::GetResult(uint8_t zeroAlpha, |
15 uint8_t maxAlpha) { | 16 uint8_t maxAlpha) { |
16 // In the transparent case, this returns 0x0000 | 17 // In the transparent case, this returns 0x0000 |
17 // In the opaque case, this returns 0xFFFF | 18 // In the opaque case, this returns 0xFFFF |
18 // If the row is neither transparent nor opaque, returns something else | 19 // If the row is neither transparent nor opaque, returns something else |
19 return (((uint16_t) maxAlpha) << 8) | zeroAlpha; | 20 return (((uint16_t) maxAlpha) << 8) | zeroAlpha; |
20 } | 21 } |
21 | 22 |
23 // samples the row. Does not do anything else but sampling | |
24 static SkSwizzler::ResultAlpha sample(void* SK_RESTRICT dstRow, const uint8_t* S K_RESTRICT src, | |
25 int width, int deltaSrc, int y, const SkPM Color ctable[]){ | |
26 uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow; | |
27 for (int x = 0; x < width; x++) { | |
28 dst[x] = src[0]; | |
29 src += deltaSrc; | |
30 } | |
31 return 0xFF; | |
scroggo
2015/07/31 13:35:33
Since this is opaque, what you want is to return 0
emmaleer
2015/07/31 18:41:56
I don't understand what you mean by "will compute
scroggo
2015/07/31 19:31:58
No, I mean the expression that is passed to the ma
emmaleer
2015/07/31 20:43:09
Acknowledged.
| |
32 } | |
22 // kIndex1, kIndex2, kIndex4 | 33 // kIndex1, kIndex2, kIndex4 |
23 | 34 |
24 static SkSwizzler::ResultAlpha swizzle_small_index_to_index( | 35 static SkSwizzler::ResultAlpha swizzle_small_index_to_index( |
25 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, | 36 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, |
26 int bitsPerPixel, int y, const SkPMColor ctable[]) { | 37 int bitsPerPixel, int y, const SkPMColor ctable[]) { |
27 | 38 |
28 uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow; | 39 uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow; |
29 INIT_RESULT_ALPHA; | 40 INIT_RESULT_ALPHA; |
30 const uint32_t pixelsPerByte = 8 / bitsPerPixel; | 41 const uint32_t pixelsPerByte = 8 / bitsPerPixel; |
31 const size_t rowBytes = compute_row_bytes_ppb(width, pixelsPerByte); | 42 const size_t rowBytes = compute_row_bytes_ppb(width, pixelsPerByte); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
65 x++; | 76 x++; |
66 } | 77 } |
67 } | 78 } |
68 return COMPUTE_RESULT_ALPHA; | 79 return COMPUTE_RESULT_ALPHA; |
69 } | 80 } |
70 | 81 |
71 // kIndex | 82 // kIndex |
72 | 83 |
73 static SkSwizzler::ResultAlpha swizzle_index_to_index( | 84 static SkSwizzler::ResultAlpha swizzle_index_to_index( |
74 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, | 85 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, |
75 int bytesPerPixel, int y, const SkPMColor ctable[]) { | 86 int deltaSrc, int y, const SkPMColor ctable[]) { |
76 | 87 |
77 uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow; | 88 uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow; |
78 memcpy(dst, src, width); | 89 if (1 == deltaSrc) { |
90 memcpy(dst, src, width); | |
91 } else { | |
92 for (int x = 0; x < width; x++) { | |
93 dst[x] = src[0]; | |
94 src += deltaSrc; | |
95 } | |
96 } | |
79 // TODO (msarett): Should we skip the loop here and guess that the row is op aque/not opaque? | 97 // TODO (msarett): Should we skip the loop here and guess that the row is op aque/not opaque? |
80 // SkScaledBitmap sampler just guesses that it is opaque. T his is dangerous | 98 // SkScaledBitmap sampler just guesses that it is opaque. T his is dangerous |
81 // and probably wrong since gif and bmp (rarely) may have al pha. | 99 // and probably wrong since gif and bmp (rarely) may have al pha. |
82 INIT_RESULT_ALPHA; | 100 INIT_RESULT_ALPHA; |
83 for (int x = 0; x < width; x++) { | 101 for (int x = 0; x < width; x++) { |
84 UPDATE_RESULT_ALPHA(ctable[src[x]] >> SK_A32_SHIFT); | 102 UPDATE_RESULT_ALPHA(ctable[src[x]] >> SK_A32_SHIFT); |
85 } | 103 } |
86 return COMPUTE_RESULT_ALPHA; | 104 return COMPUTE_RESULT_ALPHA; |
87 } | 105 } |
88 | 106 |
89 static SkSwizzler::ResultAlpha swizzle_index_to_n32( | 107 static SkSwizzler::ResultAlpha swizzle_index_to_n32( |
90 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, | 108 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, |
91 int bytesPerPixel, int y, const SkPMColor ctable[]) { | 109 int deltaSrc, int y, const SkPMColor ctable[]) { |
92 | 110 |
93 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; | 111 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; |
94 INIT_RESULT_ALPHA; | 112 INIT_RESULT_ALPHA; |
95 for (int x = 0; x < width; x++) { | 113 for (int x = 0; x < width; x++) { |
96 SkPMColor c = ctable[src[x]]; | 114 SkPMColor c = ctable[*src]; |
97 UPDATE_RESULT_ALPHA(c >> SK_A32_SHIFT); | 115 UPDATE_RESULT_ALPHA(c >> SK_A32_SHIFT); |
98 dst[x] = c; | 116 dst[x] = c; |
117 src += deltaSrc; | |
99 } | 118 } |
100 return COMPUTE_RESULT_ALPHA; | 119 return COMPUTE_RESULT_ALPHA; |
101 } | 120 } |
102 | 121 |
103 static SkSwizzler::ResultAlpha swizzle_index_to_n32_skipZ( | 122 static SkSwizzler::ResultAlpha swizzle_index_to_n32_skipZ( |
104 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, | 123 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, |
105 int bytesPerPixel, int y, const SkPMColor ctable[]) { | 124 int deltaSrc, int y, const SkPMColor ctable[]) { |
106 | 125 |
107 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; | 126 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; |
108 INIT_RESULT_ALPHA; | 127 INIT_RESULT_ALPHA; |
109 for (int x = 0; x < width; x++) { | 128 for (int x = 0; x < width; x++) { |
110 SkPMColor c = ctable[src[x]]; | 129 SkPMColor c = ctable[*src]; |
111 UPDATE_RESULT_ALPHA(c >> SK_A32_SHIFT); | 130 UPDATE_RESULT_ALPHA(c >> SK_A32_SHIFT); |
112 if (c != 0) { | 131 if (c != 0) { |
113 dst[x] = c; | 132 dst[x] = c; |
114 } | 133 } |
134 src += deltaSrc; | |
115 } | 135 } |
116 return COMPUTE_RESULT_ALPHA; | 136 return COMPUTE_RESULT_ALPHA; |
117 } | 137 } |
118 | 138 |
119 #undef A32_MASK_IN_PLACE | 139 #undef A32_MASK_IN_PLACE |
120 | 140 |
121 // kGray | 141 // kGray |
122 | 142 |
123 static SkSwizzler::ResultAlpha swizzle_gray_to_n32( | 143 static SkSwizzler::ResultAlpha swizzle_gray_to_n32( |
124 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, | 144 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, |
125 int bytesPerPixel, int y, const SkPMColor ctable[]) { | 145 int deltaSrc, int y, const SkPMColor ctable[]) { |
126 | 146 |
127 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; | 147 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; |
128 for (int x = 0; x < width; x++) { | 148 for (int x = 0; x < width; x++) { |
129 dst[x] = SkPackARGB32NoCheck(0xFF, src[x], src[x], src[x]); | 149 dst[x] = SkPackARGB32NoCheck(0xFF, *src, *src, *src); |
150 src += deltaSrc; | |
130 } | 151 } |
131 return SkSwizzler::kOpaque_ResultAlpha; | 152 return SkSwizzler::kOpaque_ResultAlpha; |
132 } | 153 } |
133 | 154 |
134 static SkSwizzler::ResultAlpha swizzle_gray_to_gray( | 155 static SkSwizzler::ResultAlpha swizzle_gray_to_gray( |
135 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, | 156 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, |
136 int bytesPerPixel, int y, const SkPMColor ctable[]) { | 157 int deltaSrc, int y, const SkPMColor ctable[]) { |
137 memcpy(dstRow, src, width); | 158 |
159 uint8_t* SK_RESTRICT dst = (uint8_t*) dstRow; | |
160 if (1 == deltaSrc) { | |
161 memcpy(dstRow, src, width); | |
162 } else { | |
163 for (int x = 0; x < width; x++) { | |
164 dst[x] = src[0]; | |
165 src += deltaSrc; | |
166 } | |
167 } | |
138 return SkSwizzler::kOpaque_ResultAlpha; | 168 return SkSwizzler::kOpaque_ResultAlpha; |
139 } | 169 } |
140 | 170 |
141 // kBGRX | 171 // kBGRX |
142 | 172 |
143 static SkSwizzler::ResultAlpha swizzle_bgrx_to_n32( | 173 static SkSwizzler::ResultAlpha swizzle_bgrx_to_n32( |
144 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, | 174 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, |
145 int bytesPerPixel, int y, const SkPMColor ctable[]) { | 175 int deltaSrc, int y, const SkPMColor ctable[]) { |
146 | 176 |
147 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; | 177 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; |
148 for (int x = 0; x < width; x++) { | 178 for (int x = 0; x < width; x++) { |
149 dst[x] = SkPackARGB32NoCheck(0xFF, src[2], src[1], src[0]); | 179 dst[x] = SkPackARGB32NoCheck(0xFF, src[2], src[1], src[0]); |
150 src += bytesPerPixel; | 180 src += deltaSrc; |
151 } | 181 } |
152 return SkSwizzler::kOpaque_ResultAlpha; | 182 return SkSwizzler::kOpaque_ResultAlpha; |
153 } | 183 } |
154 | 184 |
155 // kBGRA | 185 // kBGRA |
156 | 186 |
157 static SkSwizzler::ResultAlpha swizzle_bgra_to_n32_unpremul( | 187 static SkSwizzler::ResultAlpha swizzle_bgra_to_n32_unpremul( |
158 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, | 188 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, |
159 int bytesPerPixel, int y, const SkPMColor ctable[]) { | 189 int deltaSrc, int y, const SkPMColor ctable[]) { |
160 | 190 |
161 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; | 191 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; |
162 INIT_RESULT_ALPHA; | 192 INIT_RESULT_ALPHA; |
163 for (int x = 0; x < width; x++) { | 193 for (int x = 0; x < width; x++) { |
164 uint8_t alpha = src[3]; | 194 uint8_t alpha = src[3]; |
165 UPDATE_RESULT_ALPHA(alpha); | 195 UPDATE_RESULT_ALPHA(alpha); |
166 dst[x] = SkPackARGB32NoCheck(alpha, src[2], src[1], src[0]); | 196 dst[x] = SkPackARGB32NoCheck(alpha, src[2], src[1], src[0]); |
167 src += bytesPerPixel; | 197 src += deltaSrc; |
168 } | 198 } |
169 return COMPUTE_RESULT_ALPHA; | 199 return COMPUTE_RESULT_ALPHA; |
170 } | 200 } |
171 | 201 |
172 static SkSwizzler::ResultAlpha swizzle_bgra_to_n32_premul( | 202 static SkSwizzler::ResultAlpha swizzle_bgra_to_n32_premul( |
173 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, | 203 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, |
174 int bytesPerPixel, int y, const SkPMColor ctable[]) { | 204 int deltaSrc, int y, const SkPMColor ctable[]) { |
175 | 205 |
176 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; | 206 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; |
177 INIT_RESULT_ALPHA; | 207 INIT_RESULT_ALPHA; |
178 for (int x = 0; x < width; x++) { | 208 for (int x = 0; x < width; x++) { |
179 uint8_t alpha = src[3]; | 209 uint8_t alpha = src[3]; |
180 UPDATE_RESULT_ALPHA(alpha); | 210 UPDATE_RESULT_ALPHA(alpha); |
181 dst[x] = SkPreMultiplyARGB(alpha, src[2], src[1], src[0]); | 211 dst[x] = SkPreMultiplyARGB(alpha, src[2], src[1], src[0]); |
182 src += bytesPerPixel; | 212 src += deltaSrc; |
183 } | 213 } |
184 return COMPUTE_RESULT_ALPHA; | 214 return COMPUTE_RESULT_ALPHA; |
185 } | 215 } |
186 | 216 |
187 // n32 | 217 // n32 |
188 static SkSwizzler::ResultAlpha swizzle_rgbx_to_n32( | 218 static SkSwizzler::ResultAlpha swizzle_rgbx_to_n32( |
189 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, | 219 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, |
190 int bytesPerPixel, int y, const SkPMColor ctable[]) { | 220 int deltaSrc, int y, const SkPMColor ctable[]) { |
191 | 221 |
192 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; | 222 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; |
193 for (int x = 0; x < width; x++) { | 223 for (int x = 0; x < width; x++) { |
194 dst[x] = SkPackARGB32(0xFF, src[0], src[1], src[2]); | 224 dst[x] = SkPackARGB32(0xFF, src[0], src[1], src[2]); |
195 src += bytesPerPixel; | 225 src += deltaSrc; |
196 } | 226 } |
197 return SkSwizzler::kOpaque_ResultAlpha; | 227 return SkSwizzler::kOpaque_ResultAlpha; |
198 } | 228 } |
199 | 229 |
200 static SkSwizzler::ResultAlpha swizzle_rgba_to_n32_premul( | 230 static SkSwizzler::ResultAlpha swizzle_rgba_to_n32_premul( |
201 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, | 231 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, |
202 int bytesPerPixel, int y, const SkPMColor ctable[]) { | 232 int deltaSrc, int y, const SkPMColor ctable[]) { |
203 | 233 |
204 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; | 234 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; |
205 INIT_RESULT_ALPHA; | 235 INIT_RESULT_ALPHA; |
206 for (int x = 0; x < width; x++) { | 236 for (int x = 0; x < width; x++) { |
207 unsigned alpha = src[3]; | 237 unsigned alpha = src[3]; |
208 UPDATE_RESULT_ALPHA(alpha); | 238 UPDATE_RESULT_ALPHA(alpha); |
209 dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]); | 239 dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]); |
210 src += bytesPerPixel; | 240 src += deltaSrc; |
211 } | 241 } |
212 return COMPUTE_RESULT_ALPHA; | 242 return COMPUTE_RESULT_ALPHA; |
213 } | 243 } |
214 | 244 |
215 static SkSwizzler::ResultAlpha swizzle_rgba_to_n32_unpremul( | 245 static SkSwizzler::ResultAlpha swizzle_rgba_to_n32_unpremul( |
216 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, | 246 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, |
217 int bytesPerPixel, int y, const SkPMColor ctable[]) { | 247 int deltaSrc, int y, const SkPMColor ctable[]) { |
218 | 248 |
219 uint32_t* SK_RESTRICT dst = reinterpret_cast<uint32_t*>(dstRow); | 249 uint32_t* SK_RESTRICT dst = reinterpret_cast<uint32_t*>(dstRow); |
220 INIT_RESULT_ALPHA; | 250 INIT_RESULT_ALPHA; |
221 for (int x = 0; x < width; x++) { | 251 for (int x = 0; x < width; x++) { |
222 unsigned alpha = src[3]; | 252 unsigned alpha = src[3]; |
223 UPDATE_RESULT_ALPHA(alpha); | 253 UPDATE_RESULT_ALPHA(alpha); |
224 dst[x] = SkPackARGB32NoCheck(alpha, src[0], src[1], src[2]); | 254 dst[x] = SkPackARGB32NoCheck(alpha, src[0], src[1], src[2]); |
225 src += bytesPerPixel; | 255 src += deltaSrc; |
226 } | 256 } |
227 return COMPUTE_RESULT_ALPHA; | 257 return COMPUTE_RESULT_ALPHA; |
228 } | 258 } |
229 | 259 |
230 static SkSwizzler::ResultAlpha swizzle_rgba_to_n32_premul_skipZ( | 260 static SkSwizzler::ResultAlpha swizzle_rgba_to_n32_premul_skipZ( |
231 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, | 261 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int width, |
232 int bytesPerPixel, int y, const SkPMColor ctable[]) { | 262 int deltaSrc, int y, const SkPMColor ctable[]) { |
233 | 263 |
234 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; | 264 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; |
235 INIT_RESULT_ALPHA; | 265 INIT_RESULT_ALPHA; |
236 for (int x = 0; x < width; x++) { | 266 for (int x = 0; x < width; x++) { |
237 unsigned alpha = src[3]; | 267 unsigned alpha = src[3]; |
238 UPDATE_RESULT_ALPHA(alpha); | 268 UPDATE_RESULT_ALPHA(alpha); |
239 if (0 != alpha) { | 269 if (0 != alpha) { |
240 dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]); | 270 dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]); |
241 } | 271 } |
242 src += bytesPerPixel; | 272 src += deltaSrc; |
243 } | 273 } |
244 return COMPUTE_RESULT_ALPHA; | 274 return COMPUTE_RESULT_ALPHA; |
245 } | 275 } |
246 | 276 |
247 /** | 277 /** |
248 FIXME: This was my idea to cheat in order to continue taking advantage of sk ipping zeroes. | 278 FIXME: This was my idea to cheat in order to continue taking advantage of sk ipping zeroes. |
249 This would be fine for drawing normally, but not for drawing with transfer m odes. Being | 279 This would be fine for drawing normally, but not for drawing with transfer m odes. Being |
250 honest means we can draw correctly with transfer modes, with the cost of not being able | 280 honest means we can draw correctly with transfer modes, with the cost of not being able |
251 to take advantage of Android's free unwritten pages. Something to keep in mi nd when we | 281 to take advantage of Android's free unwritten pages. Something to keep in mi nd when we |
252 decide whether to switch to unpremul default. | 282 decide whether to switch to unpremul default. |
(...skipping 13 matching lines...) Expand all Loading... | |
266 } | 296 } |
267 src += deltaSrc; | 297 src += deltaSrc; |
268 alphaMask &= alpha; | 298 alphaMask &= alpha; |
269 } | 299 } |
270 return alphaMask != 0xFF; | 300 return alphaMask != 0xFF; |
271 } | 301 } |
272 */ | 302 */ |
273 | 303 |
274 SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, | 304 SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, |
275 const SkPMColor* ctable, | 305 const SkPMColor* ctable, |
276 const SkImageInfo& info, void* dst, | 306 const SkImageInfo& dstInfo, void* dst, |
277 size_t dstRowBytes, | 307 size_t dstRowBytes, |
278 SkCodec::ZeroInitialized zeroInit) { | 308 SkCodec::ZeroInitialized zeroInit, |
279 if (info.colorType() == kUnknown_SkColorType || kUnknown == sc) { | 309 int srcWidth) { |
310 if (dstInfo.colorType() == kUnknown_SkColorType || kUnknown == sc) { | |
280 return NULL; | 311 return NULL; |
281 } | 312 } |
282 if (info.minRowBytes() > dstRowBytes) { | 313 if (dstInfo.minRowBytes() > dstRowBytes) { |
283 return NULL; | 314 return NULL; |
284 } | 315 } |
285 if ((kIndex == sc || kIndex4 == sc || kIndex2 == sc || kIndex1 == sc) | 316 if ((kIndex == sc || kIndex4 == sc || kIndex2 == sc || kIndex1 == sc) |
286 && NULL == ctable) { | 317 && NULL == ctable) { |
287 return NULL; | 318 return NULL; |
288 } | 319 } |
320 | |
289 RowProc proc = NULL; | 321 RowProc proc = NULL; |
322 | |
290 switch (sc) { | 323 switch (sc) { |
291 case kIndex1: | 324 case kIndex1: |
292 case kIndex2: | 325 case kIndex2: |
293 case kIndex4: | 326 case kIndex4: |
294 switch (info.colorType()) { | 327 switch (dstInfo.colorType()) { |
295 case kN32_SkColorType: | 328 case kN32_SkColorType: |
296 proc = &swizzle_small_index_to_n32; | 329 proc = &swizzle_small_index_to_n32; |
297 break; | 330 break; |
298 case kIndex_8_SkColorType: | 331 case kIndex_8_SkColorType: |
299 proc = &swizzle_small_index_to_index; | 332 proc = &swizzle_small_index_to_index; |
300 break; | 333 break; |
301 default: | 334 default: |
302 break; | 335 break; |
303 } | 336 } |
304 break; | 337 break; |
305 case kIndex: | 338 case kIndex: |
306 switch (info.colorType()) { | 339 switch (dstInfo.colorType()) { |
307 case kN32_SkColorType: | 340 case kN32_SkColorType: |
308 // We assume the color premultiplied ctable (or not) as desi red. | 341 // We assume the color premultiplied ctable (or not) as desi red. |
309 if (SkCodec::kYes_ZeroInitialized == zeroInit) { | 342 if (SkCodec::kYes_ZeroInitialized == zeroInit) { |
310 proc = &swizzle_index_to_n32_skipZ; | 343 proc = &swizzle_index_to_n32_skipZ; |
311 break; | 344 break; |
312 } else { | 345 } else { |
313 proc = &swizzle_index_to_n32; | 346 proc = &swizzle_index_to_n32; |
314 break; | 347 break; |
315 } | 348 } |
316 break; | 349 break; |
317 case kIndex_8_SkColorType: | 350 case kIndex_8_SkColorType: |
318 proc = &swizzle_index_to_index; | 351 proc = &swizzle_index_to_index; |
319 break; | 352 break; |
320 default: | 353 default: |
321 break; | 354 break; |
322 } | 355 } |
323 break; | 356 break; |
324 case kGray: | 357 case kGray: |
325 switch (info.colorType()) { | 358 switch (dstInfo.colorType()) { |
326 case kN32_SkColorType: | 359 case kN32_SkColorType: |
327 proc = &swizzle_gray_to_n32; | 360 proc = &swizzle_gray_to_n32; |
328 break; | 361 break; |
329 case kGray_8_SkColorType: | 362 case kGray_8_SkColorType: |
330 proc = &swizzle_gray_to_gray; | 363 proc = &swizzle_gray_to_gray; |
331 default: | 364 default: |
332 break; | 365 break; |
333 } | 366 } |
334 break; | 367 break; |
335 case kBGR: | 368 case kBGR: |
336 case kBGRX: | 369 case kBGRX: |
337 switch (info.colorType()) { | 370 switch (dstInfo.colorType()) { |
338 case kN32_SkColorType: | 371 case kN32_SkColorType: |
339 proc = &swizzle_bgrx_to_n32; | 372 proc = &swizzle_bgrx_to_n32; |
340 break; | 373 break; |
341 default: | 374 default: |
342 break; | 375 break; |
343 } | 376 } |
344 break; | 377 break; |
345 case kBGRA: | 378 case kBGRA: |
346 switch (info.colorType()) { | 379 switch (dstInfo.colorType()) { |
347 case kN32_SkColorType: | 380 case kN32_SkColorType: |
348 switch (info.alphaType()) { | 381 switch (dstInfo.alphaType()) { |
349 case kUnpremul_SkAlphaType: | 382 case kUnpremul_SkAlphaType: |
350 proc = &swizzle_bgra_to_n32_unpremul; | 383 proc = &swizzle_bgra_to_n32_unpremul; |
351 break; | 384 break; |
352 case kPremul_SkAlphaType: | 385 case kPremul_SkAlphaType: |
353 proc = &swizzle_bgra_to_n32_premul; | 386 proc = &swizzle_bgra_to_n32_premul; |
354 break; | 387 break; |
355 default: | 388 default: |
356 break; | 389 break; |
357 } | 390 } |
358 break; | 391 break; |
359 default: | 392 default: |
360 break; | 393 break; |
361 } | 394 } |
362 break; | 395 break; |
363 case kRGBX: | 396 case kRGBX: |
364 // TODO: Support other swizzles. | 397 // TODO: Support other swizzles. |
365 switch (info.colorType()) { | 398 switch (dstInfo.colorType()) { |
366 case kN32_SkColorType: | 399 case kN32_SkColorType: |
367 proc = &swizzle_rgbx_to_n32; | 400 proc = &swizzle_rgbx_to_n32; |
368 break; | 401 break; |
369 default: | 402 default: |
370 break; | 403 break; |
371 } | 404 } |
372 break; | 405 break; |
373 case kRGBA: | 406 case kRGBA: |
374 switch (info.colorType()) { | 407 switch (dstInfo.colorType()) { |
375 case kN32_SkColorType: | 408 case kN32_SkColorType: |
376 if (info.alphaType() == kUnpremul_SkAlphaType) { | 409 if (dstInfo.alphaType() == kUnpremul_SkAlphaType) { |
377 // Respect zeroInit? | 410 // Respect zeroInit? |
378 proc = &swizzle_rgba_to_n32_unpremul; | 411 proc = &swizzle_rgba_to_n32_unpremul; |
379 } else { | 412 } else { |
380 if (SkCodec::kYes_ZeroInitialized == zeroInit) { | 413 if (SkCodec::kYes_ZeroInitialized == zeroInit) { |
381 proc = &swizzle_rgba_to_n32_premul_skipZ; | 414 proc = &swizzle_rgba_to_n32_premul_skipZ; |
382 } else { | 415 } else { |
383 proc = &swizzle_rgba_to_n32_premul; | 416 proc = &swizzle_rgba_to_n32_premul; |
384 } | 417 } |
385 } | 418 } |
386 break; | 419 break; |
387 default: | 420 default: |
388 break; | 421 break; |
389 } | 422 } |
390 break; | 423 break; |
391 case kRGB: | 424 case kRGB: |
392 switch (info.colorType()) { | 425 switch (dstInfo.colorType()) { |
393 case kN32_SkColorType: | 426 case kN32_SkColorType: |
394 proc = &swizzle_rgbx_to_n32; | 427 proc = &swizzle_rgbx_to_n32; |
395 break; | 428 break; |
396 default: | 429 default: |
397 break; | 430 break; |
398 } | 431 } |
399 break; | 432 break; |
433 case kRGB_565: | |
434 switch (dstInfo.colorType()) { | |
435 case kRGB_565_SkColorType: | |
436 proc = &sample; | |
437 break; | |
438 default: | |
439 break; | |
440 } | |
400 default: | 441 default: |
401 break; | 442 break; |
402 } | 443 } |
403 if (NULL == proc) { | 444 if (NULL == proc) { |
404 return NULL; | 445 return NULL; |
405 } | 446 } |
406 | 447 |
407 // Store deltaSrc in bytes if it is an even multiple, otherwise use bits | 448 // Store deltaSrc in bytes if it is an even multiple, otherwise use bits |
408 int deltaSrc = SkIsAlign8(BitsPerPixel(sc)) ? BytesPerPixel(sc) : | 449 int deltaSrc = SkIsAlign8(BitsPerPixel(sc)) ? BytesPerPixel(sc) : |
409 BitsPerPixel(sc); | 450 BitsPerPixel(sc); |
410 return SkNEW_ARGS(SkSwizzler, (proc, ctable, deltaSrc, info, dst, | 451 |
411 dstRowBytes)); | 452 int sampleX = SkScaledCodec::get_sample_size(srcWidth, dstInfo.width()); |
453 | |
454 return SkNEW_ARGS(SkSwizzler, (proc, ctable, deltaSrc, dstInfo, dst, | |
455 dstRowBytes, sampleX)); | |
412 } | 456 } |
413 | 457 |
414 SkSwizzler::SkSwizzler(RowProc proc, const SkPMColor* ctable, | 458 SkSwizzler::SkSwizzler(RowProc proc, const SkPMColor* ctable, |
415 int deltaSrc, const SkImageInfo& info, void* dst, | 459 int deltaSrc, const SkImageInfo& info, void* dst, |
416 size_t rowBytes) | 460 size_t rowBytes, int sampleX) |
417 : fRowProc(proc) | 461 : fRowProc(proc) |
418 , fColorTable(ctable) | 462 , fColorTable(ctable) |
419 , fDeltaSrc(deltaSrc) | 463 , fDeltaSrc(deltaSrc) |
420 , fDstInfo(info) | 464 , fDstInfo(info) |
421 , fDstRow(dst) | 465 , fDstRow(dst) |
422 , fDstRowBytes(rowBytes) | 466 , fDstRowBytes(rowBytes) |
423 , fCurrY(0) | 467 , fCurrY(0) |
468 , fSampleX(sampleX) | |
469 , fX0(sampleX == 1 ? 0 : sampleX >> 1) | |
424 { | 470 { |
471 // check that fX0 is less than original width | |
472 SkASSERT(fX0 >= 0 && fX0 < fDstInfo.width() * fSampleX); | |
425 SkDEBUGCODE(fNextMode = kUninitialized_NextMode); | 473 SkDEBUGCODE(fNextMode = kUninitialized_NextMode); |
426 } | 474 } |
427 | 475 |
428 SkSwizzler::ResultAlpha SkSwizzler::next(const uint8_t* SK_RESTRICT src) { | 476 SkSwizzler::ResultAlpha SkSwizzler::next(const uint8_t* SK_RESTRICT src) { |
429 SkASSERT(0 <= fCurrY && fCurrY < fDstInfo.height()); | 477 SkASSERT(0 <= fCurrY && fCurrY < fDstInfo.height()); |
430 SkASSERT(fDstRow != NULL); | 478 SkASSERT(fDstRow != NULL); |
431 SkASSERT(kDesignateRow_NextMode != fNextMode); | 479 SkASSERT(kDesignateRow_NextMode != fNextMode); |
432 SkDEBUGCODE(fNextMode = kConsecutive_NextMode); | 480 SkDEBUGCODE(fNextMode = kConsecutive_NextMode); |
433 | 481 |
434 // Decode a row | 482 // Decode a row |
435 const ResultAlpha result = fRowProc(fDstRow, src, fDstInfo.width(), | 483 const ResultAlpha result = fRowProc(fDstRow, src + fX0 * fDeltaSrc, fDstInfo .width(), |
436 fDeltaSrc, fCurrY, fColorTable); | 484 fSampleX * fDeltaSrc, fCurrY, fColorTable); |
437 | 485 |
438 // Move to the next row and return the result | 486 // Move to the next row and return the result |
439 fCurrY++; | 487 fCurrY++; |
440 fDstRow = SkTAddOffset<void>(fDstRow, fDstRowBytes); | 488 fDstRow = SkTAddOffset<void>(fDstRow, fDstRowBytes); |
441 return result; | 489 return result; |
442 } | 490 } |
443 | 491 |
444 SkSwizzler::ResultAlpha SkSwizzler::next(const uint8_t* SK_RESTRICT src, | 492 SkSwizzler::ResultAlpha SkSwizzler::next(const uint8_t* SK_RESTRICT src, |
445 int y) { | 493 int y) { |
446 SkASSERT(0 <= y && y < fDstInfo.height()); | 494 SkASSERT(0 <= y && y < fDstInfo.height()); |
447 SkASSERT(kConsecutive_NextMode != fNextMode); | 495 SkASSERT(kConsecutive_NextMode != fNextMode); |
448 SkDEBUGCODE(fNextMode = kDesignateRow_NextMode); | 496 SkDEBUGCODE(fNextMode = kDesignateRow_NextMode); |
449 | 497 |
450 // Choose the row | 498 // Choose the row |
451 void* row = SkTAddOffset<void>(fDstRow, y*fDstRowBytes); | 499 void* row = SkTAddOffset<void>(fDstRow, y*fDstRowBytes); |
452 | 500 |
453 // Decode the row | 501 // Decode the row |
454 return fRowProc(row, src, fDstInfo.width(), fDeltaSrc, fCurrY, | 502 return fRowProc(row, src + fX0 * fDeltaSrc, fDstInfo.width(), fSampleX * fDe ltaSrc, fCurrY, |
455 fColorTable); | 503 fColorTable); |
456 } | 504 } |
457 | 505 |
458 void SkSwizzler::Fill(void* dstStartRow, const SkImageInfo& dstInfo, size_t dstR owBytes, | 506 void SkSwizzler::Fill(void* dstStartRow, const SkImageInfo& dstInfo, size_t dstR owBytes, |
459 uint32_t numRows, uint32_t colorOrIndex, const SkPMColor* colorTable) { | 507 uint32_t numRows, uint32_t colorOrIndex, const SkPMColor* colorTable) { |
460 SkASSERT(dstStartRow != NULL); | 508 SkASSERT(dstStartRow != NULL); |
461 SkASSERT(numRows <= (uint32_t) dstInfo.height()); | 509 SkASSERT(numRows <= (uint32_t) dstInfo.height()); |
462 | 510 |
463 // Calculate bytes to fill. We use getSafeSize since the last row may not b e padded. | 511 // Calculate bytes to fill. We use getSafeSize since the last row may not b e padded. |
464 const size_t bytesToFill = dstInfo.makeWH(dstInfo.width(), numRows).getSafeS ize(dstRowBytes); | 512 const size_t bytesToFill = dstInfo.makeWH(dstInfo.width(), numRows).getSafeS ize(dstRowBytes); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
505 // bits of SK_ColorBLACK are identical to the grayscale representati on | 553 // bits of SK_ColorBLACK are identical to the grayscale representati on |
506 // for black. | 554 // for black. |
507 memset(dstStartRow, (uint8_t) colorOrIndex, bytesToFill); | 555 memset(dstStartRow, (uint8_t) colorOrIndex, bytesToFill); |
508 break; | 556 break; |
509 default: | 557 default: |
510 SkCodecPrintf("Error: Unsupported dst color type for fill(). Doing nothing.\n"); | 558 SkCodecPrintf("Error: Unsupported dst color type for fill(). Doing nothing.\n"); |
511 SkASSERT(false); | 559 SkASSERT(false); |
512 break; | 560 break; |
513 } | 561 } |
514 } | 562 } |
OLD | NEW |