| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright 2007, The Android Open Source Project | |
| 3 * | |
| 4 * Licensed under the Apache License, Version 2.0 (the "License"); | |
| 5 * you may not use this file except in compliance with the License. | |
| 6 * You may obtain a copy of the License at | |
| 7 * | |
| 8 * http://www.apache.org/licenses/LICENSE-2.0 | |
| 9 * | |
| 10 * Unless required by applicable law or agreed to in writing, software | |
| 11 * distributed under the License is distributed on an "AS IS" BASIS, | |
| 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 13 * See the License for the specific language governing permissions and | |
| 14 * limitations under the License. | |
| 15 */ | |
| 16 | |
| 17 #include "SkScaledBitmapSampler.h" | |
| 18 #include "SkBitmap.h" | |
| 19 #include "SkColorPriv.h" | |
| 20 #include "SkDither.h" | |
| 21 | |
| 22 // 8888 | |
| 23 | |
| 24 static bool Sample_Gray_D8888(void* SK_RESTRICT dstRow, | |
| 25 const uint8_t* SK_RESTRICT src, | |
| 26 int width, int deltaSrc, int) { | |
| 27 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; | |
| 28 for (int x = 0; x < width; x++) { | |
| 29 dst[x] = SkPackARGB32(0xFF, src[0], src[0], src[0]); | |
| 30 src += deltaSrc; | |
| 31 } | |
| 32 return false; | |
| 33 } | |
| 34 | |
| 35 static bool Sample_RGBx_D8888(void* SK_RESTRICT dstRow, | |
| 36 const uint8_t* SK_RESTRICT src, | |
| 37 int width, int deltaSrc, int) { | |
| 38 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; | |
| 39 for (int x = 0; x < width; x++) { | |
| 40 dst[x] = SkPackARGB32(0xFF, src[0], src[1], src[2]); | |
| 41 src += deltaSrc; | |
| 42 } | |
| 43 return false; | |
| 44 } | |
| 45 | |
| 46 static bool Sample_RGBA_D8888(void* SK_RESTRICT dstRow, | |
| 47 const uint8_t* SK_RESTRICT src, | |
| 48 int width, int deltaSrc, int) { | |
| 49 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; | |
| 50 unsigned alphaMask = 0xFF; | |
| 51 for (int x = 0; x < width; x++) { | |
| 52 unsigned alpha = src[3]; | |
| 53 dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]); | |
| 54 src += deltaSrc; | |
| 55 alphaMask &= alpha; | |
| 56 } | |
| 57 return alphaMask != 0xFF; | |
| 58 } | |
| 59 | |
| 60 // 565 | |
| 61 | |
| 62 static bool Sample_Gray_D565(void* SK_RESTRICT dstRow, | |
| 63 const uint8_t* SK_RESTRICT src, | |
| 64 int width, int deltaSrc, int) { | |
| 65 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; | |
| 66 for (int x = 0; x < width; x++) { | |
| 67 dst[x] = SkPack888ToRGB16(src[0], src[0], src[0]); | |
| 68 src += deltaSrc; | |
| 69 } | |
| 70 return false; | |
| 71 } | |
| 72 | |
| 73 static bool Sample_Gray_D565_D(void* SK_RESTRICT dstRow, | |
| 74 const uint8_t* SK_RESTRICT src, | |
| 75 int width, int deltaSrc, int y) { | |
| 76 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; | |
| 77 DITHER_565_SCAN(y); | |
| 78 for (int x = 0; x < width; x++) { | |
| 79 dst[x] = SkDitherRGBTo565(src[0], src[0], src[0], DITHER_VALUE(x)); | |
| 80 src += deltaSrc; | |
| 81 } | |
| 82 return false; | |
| 83 } | |
| 84 | |
| 85 static bool Sample_RGBx_D565(void* SK_RESTRICT dstRow, | |
| 86 const uint8_t* SK_RESTRICT src, | |
| 87 int width, int deltaSrc, int) { | |
| 88 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; | |
| 89 for (int x = 0; x < width; x++) { | |
| 90 dst[x] = SkPack888ToRGB16(src[0], src[1], src[2]); | |
| 91 src += deltaSrc; | |
| 92 } | |
| 93 return false; | |
| 94 } | |
| 95 | |
| 96 static bool Sample_RGBx_D565_D(void* SK_RESTRICT dstRow, | |
| 97 const uint8_t* SK_RESTRICT src, | |
| 98 int width, int deltaSrc, int y) { | |
| 99 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; | |
| 100 DITHER_565_SCAN(y); | |
| 101 for (int x = 0; x < width; x++) { | |
| 102 dst[x] = SkDitherRGBTo565(src[0], src[1], src[2], DITHER_VALUE(x)); | |
| 103 src += deltaSrc; | |
| 104 } | |
| 105 return false; | |
| 106 } | |
| 107 | |
| 108 // 4444 | |
| 109 | |
| 110 static bool Sample_Gray_D4444(void* SK_RESTRICT dstRow, | |
| 111 const uint8_t* SK_RESTRICT src, | |
| 112 int width, int deltaSrc, int) { | |
| 113 SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; | |
| 114 for (int x = 0; x < width; x++) { | |
| 115 unsigned gray = src[0] >> 4; | |
| 116 dst[x] = SkPackARGB4444(0xF, gray, gray, gray); | |
| 117 src += deltaSrc; | |
| 118 } | |
| 119 return false; | |
| 120 } | |
| 121 | |
| 122 static bool Sample_Gray_D4444_D(void* SK_RESTRICT dstRow, | |
| 123 const uint8_t* SK_RESTRICT src, | |
| 124 int width, int deltaSrc, int y) { | |
| 125 SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; | |
| 126 DITHER_4444_SCAN(y); | |
| 127 for (int x = 0; x < width; x++) { | |
| 128 dst[x] = SkDitherARGB32To4444(0xFF, src[0], src[0], src[0], | |
| 129 DITHER_VALUE(x)); | |
| 130 src += deltaSrc; | |
| 131 } | |
| 132 return false; | |
| 133 } | |
| 134 | |
| 135 static bool Sample_RGBx_D4444(void* SK_RESTRICT dstRow, | |
| 136 const uint8_t* SK_RESTRICT src, | |
| 137 int width, int deltaSrc, int) { | |
| 138 SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; | |
| 139 for (int x = 0; x < width; x++) { | |
| 140 dst[x] = SkPackARGB4444(0xF, src[0] >> 4, src[1] >> 4, src[2] >> 4); | |
| 141 src += deltaSrc; | |
| 142 } | |
| 143 return false; | |
| 144 } | |
| 145 | |
| 146 static bool Sample_RGBx_D4444_D(void* SK_RESTRICT dstRow, | |
| 147 const uint8_t* SK_RESTRICT src, | |
| 148 int width, int deltaSrc, int y) { | |
| 149 SkPMColor16* dst = (SkPMColor16*)dstRow; | |
| 150 DITHER_4444_SCAN(y); | |
| 151 | |
| 152 for (int x = 0; x < width; x++) { | |
| 153 dst[x] = SkDitherARGB32To4444(0xFF, src[0], src[1], src[2], | |
| 154 DITHER_VALUE(x)); | |
| 155 src += deltaSrc; | |
| 156 } | |
| 157 return false; | |
| 158 } | |
| 159 | |
| 160 static bool Sample_RGBA_D4444(void* SK_RESTRICT dstRow, | |
| 161 const uint8_t* SK_RESTRICT src, | |
| 162 int width, int deltaSrc, int) { | |
| 163 SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; | |
| 164 unsigned alphaMask = 0xFF; | |
| 165 | |
| 166 for (int x = 0; x < width; x++) { | |
| 167 unsigned alpha = src[3]; | |
| 168 SkPMColor c = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]); | |
| 169 dst[x] = SkPixel32ToPixel4444(c); | |
| 170 src += deltaSrc; | |
| 171 alphaMask &= alpha; | |
| 172 } | |
| 173 return alphaMask != 0xFF; | |
| 174 } | |
| 175 | |
| 176 static bool Sample_RGBA_D4444_D(void* SK_RESTRICT dstRow, | |
| 177 const uint8_t* SK_RESTRICT src, | |
| 178 int width, int deltaSrc, int y) { | |
| 179 SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; | |
| 180 unsigned alphaMask = 0xFF; | |
| 181 DITHER_4444_SCAN(y); | |
| 182 | |
| 183 for (int x = 0; x < width; x++) { | |
| 184 unsigned alpha = src[3]; | |
| 185 SkPMColor c = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]); | |
| 186 dst[x] = SkDitherARGB32To4444(c, DITHER_VALUE(x)); | |
| 187 src += deltaSrc; | |
| 188 alphaMask &= alpha; | |
| 189 } | |
| 190 return alphaMask != 0xFF; | |
| 191 } | |
| 192 | |
| 193 // Index | |
| 194 | |
| 195 static bool Sample_Index_DI(void* SK_RESTRICT dstRow, | |
| 196 const uint8_t* SK_RESTRICT src, | |
| 197 int width, int deltaSrc, int) { | |
| 198 if (1 == deltaSrc) { | |
| 199 memcpy(dstRow, src, width); | |
| 200 } else { | |
| 201 uint8_t* SK_RESTRICT dst = (uint8_t*)dstRow; | |
| 202 for (int x = 0; x < width; x++) { | |
| 203 dst[x] = src[0]; | |
| 204 src += deltaSrc; | |
| 205 } | |
| 206 } | |
| 207 return false; | |
| 208 } | |
| 209 | |
| 210 /////////////////////////////////////////////////////////////////////////////// | |
| 211 | |
| 212 #include "SkScaledBitmapSampler.h" | |
| 213 | |
| 214 SkScaledBitmapSampler::SkScaledBitmapSampler(int width, int height, | |
| 215 int sampleSize) { | |
| 216 if (width <= 0 || height <= 0) { | |
| 217 sk_throw(); | |
| 218 } | |
| 219 | |
| 220 if (sampleSize <= 1) { | |
| 221 fScaledWidth = width; | |
| 222 fScaledHeight = height; | |
| 223 fX0 = fY0 = 0; | |
| 224 fDX = fDY = 1; | |
| 225 return; | |
| 226 } | |
| 227 | |
| 228 int dx = SkMin32(sampleSize, width); | |
| 229 int dy = SkMin32(sampleSize, height); | |
| 230 | |
| 231 fScaledWidth = width / dx; | |
| 232 fScaledHeight = height / dy; | |
| 233 | |
| 234 SkASSERT(fScaledWidth > 0); | |
| 235 SkASSERT(fScaledHeight > 0); | |
| 236 | |
| 237 fX0 = dx >> 1; | |
| 238 fY0 = dy >> 1; | |
| 239 | |
| 240 SkASSERT(fX0 >= 0 && fX0 < width); | |
| 241 SkASSERT(fY0 >= 0 && fY0 < height); | |
| 242 | |
| 243 fDX = dx; | |
| 244 fDY = dy; | |
| 245 | |
| 246 SkASSERT(fDX > 0 && (fX0 + fDX * (fScaledWidth - 1)) < width); | |
| 247 SkASSERT(fDY > 0 && (fY0 + fDY * (fScaledHeight - 1)) < height); | |
| 248 | |
| 249 fRowProc = NULL; | |
| 250 } | |
| 251 | |
| 252 bool SkScaledBitmapSampler::begin(SkBitmap* dst, SrcConfig sc, bool dither) { | |
| 253 static const RowProc gProcs[] = { | |
| 254 // 8888 (no dither distinction) | |
| 255 Sample_Gray_D8888, Sample_Gray_D8888, | |
| 256 Sample_RGBx_D8888, Sample_RGBx_D8888, | |
| 257 Sample_RGBA_D8888, Sample_RGBA_D8888, | |
| 258 NULL, NULL, | |
| 259 // 565 (no alpha distinction) | |
| 260 Sample_Gray_D565, Sample_Gray_D565_D, | |
| 261 Sample_RGBx_D565, Sample_RGBx_D565_D, | |
| 262 Sample_RGBx_D565, Sample_RGBx_D565_D, | |
| 263 NULL, NULL, | |
| 264 // 4444 | |
| 265 Sample_Gray_D4444, Sample_Gray_D4444_D, | |
| 266 Sample_RGBx_D4444, Sample_RGBx_D4444_D, | |
| 267 Sample_RGBA_D4444, Sample_RGBA_D4444_D, | |
| 268 NULL, NULL, | |
| 269 // Index8 | |
| 270 NULL, NULL, | |
| 271 NULL, NULL, | |
| 272 NULL, NULL, | |
| 273 Sample_Index_DI, Sample_Index_DI, | |
| 274 }; | |
| 275 | |
| 276 | |
| 277 int index = 0; | |
| 278 if (dither) { | |
| 279 index += 1; | |
| 280 } | |
| 281 switch (sc) { | |
| 282 case SkScaledBitmapSampler::kGray: | |
| 283 fSrcPixelSize = 1; | |
| 284 index += 0; | |
| 285 break; | |
| 286 case SkScaledBitmapSampler::kRGB: | |
| 287 fSrcPixelSize = 3; | |
| 288 index += 2; | |
| 289 break; | |
| 290 case SkScaledBitmapSampler::kRGBX: | |
| 291 fSrcPixelSize = 4; | |
| 292 index += 2; | |
| 293 break; | |
| 294 case SkScaledBitmapSampler::kRGBA: | |
| 295 fSrcPixelSize = 4; | |
| 296 index += 4; | |
| 297 break; | |
| 298 case SkScaledBitmapSampler::kIndex: | |
| 299 fSrcPixelSize = 1; | |
| 300 index += 6; | |
| 301 break; | |
| 302 default: | |
| 303 return false; | |
| 304 } | |
| 305 | |
| 306 switch (dst->config()) { | |
| 307 case SkBitmap::kARGB_8888_Config: | |
| 308 index += 0; | |
| 309 break; | |
| 310 case SkBitmap::kRGB_565_Config: | |
| 311 index += 8; | |
| 312 break; | |
| 313 case SkBitmap::kARGB_4444_Config: | |
| 314 index += 16; | |
| 315 break; | |
| 316 case SkBitmap::kIndex8_Config: | |
| 317 index += 24; | |
| 318 break; | |
| 319 default: | |
| 320 return false; | |
| 321 } | |
| 322 | |
| 323 fRowProc = gProcs[index]; | |
| 324 fDstRow = (char*)dst->getPixels(); | |
| 325 fDstRowBytes = dst->rowBytes(); | |
| 326 fCurrY = 0; | |
| 327 return fRowProc != NULL; | |
| 328 } | |
| 329 | |
| 330 bool SkScaledBitmapSampler::next(const uint8_t* SK_RESTRICT src) { | |
| 331 SkASSERT((unsigned)fCurrY < (unsigned)fScaledHeight); | |
| 332 | |
| 333 bool hadAlpha = fRowProc(fDstRow, src + fX0 * fSrcPixelSize, fScaledWidth, | |
| 334 fDX * fSrcPixelSize, fCurrY); | |
| 335 fDstRow += fDstRowBytes; | |
| 336 fCurrY += 1; | |
| 337 return hadAlpha; | |
| 338 } | |
| OLD | NEW |