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