| OLD | NEW |
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2008 The Android Open Source Project | 3 * Copyright 2008 The Android Open Source Project |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 | 9 |
| 10 #include "SkBitmap.h" | 10 #include "SkBitmap.h" |
| 11 #include "SkColorPriv.h" | 11 #include "SkColorPriv.h" |
| 12 #include "SkDither.h" | 12 #include "SkDither.h" |
| 13 #include "SkFlattenable.h" | 13 #include "SkFlattenable.h" |
| 14 #include "SkImagePriv.h" | 14 #include "SkImagePriv.h" |
| 15 #include "SkMallocPixelRef.h" | 15 #include "SkMallocPixelRef.h" |
| 16 #include "SkMask.h" | 16 #include "SkMask.h" |
| 17 #include "SkReadBuffer.h" | 17 #include "SkReadBuffer.h" |
| 18 #include "SkWriteBuffer.h" | 18 #include "SkWriteBuffer.h" |
| 19 #include "SkPixelRef.h" | 19 #include "SkPixelRef.h" |
| 20 #include "SkThread.h" | 20 #include "SkThread.h" |
| 21 #include "SkUnPreMultiply.h" | 21 #include "SkUnPreMultiply.h" |
| 22 #include "SkUtils.h" | 22 #include "SkUtils.h" |
| 23 #include "SkValidationUtils.h" | 23 #include "SkValidationUtils.h" |
| 24 #include "SkPackBits.h" | 24 #include "SkPackBits.h" |
| 25 #include <new> | 25 #include <new> |
| 26 | 26 |
| 27 static bool reset_return_false(SkBitmap* bm) { | |
| 28 bm->reset(); | |
| 29 return false; | |
| 30 } | |
| 31 | |
| 32 struct MipLevel { | 27 struct MipLevel { |
| 33 void* fPixels; | 28 void* fPixels; |
| 34 uint32_t fRowBytes; | 29 uint32_t fRowBytes; |
| 35 uint32_t fWidth, fHeight; | 30 uint32_t fWidth, fHeight; |
| 36 }; | 31 }; |
| 37 | 32 |
| 38 struct SkBitmap::MipMap : SkNoncopyable { | 33 struct SkBitmap::MipMap : SkNoncopyable { |
| 39 int32_t fRefCnt; | 34 int32_t fRefCnt; |
| 40 int fLevelCount; | 35 int fLevelCount; |
| 41 // MipLevel fLevel[fLevelCount]; | 36 // MipLevel fLevel[fLevelCount]; |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 123 return *this; | 118 return *this; |
| 124 } | 119 } |
| 125 | 120 |
| 126 void SkBitmap::swap(SkBitmap& other) { | 121 void SkBitmap::swap(SkBitmap& other) { |
| 127 SkTSwap(fColorTable, other.fColorTable); | 122 SkTSwap(fColorTable, other.fColorTable); |
| 128 SkTSwap(fPixelRef, other.fPixelRef); | 123 SkTSwap(fPixelRef, other.fPixelRef); |
| 129 SkTSwap(fPixelRefOrigin, other.fPixelRefOrigin); | 124 SkTSwap(fPixelRefOrigin, other.fPixelRefOrigin); |
| 130 SkTSwap(fPixelLockCount, other.fPixelLockCount); | 125 SkTSwap(fPixelLockCount, other.fPixelLockCount); |
| 131 SkTSwap(fMipMap, other.fMipMap); | 126 SkTSwap(fMipMap, other.fMipMap); |
| 132 SkTSwap(fPixels, other.fPixels); | 127 SkTSwap(fPixels, other.fPixels); |
| 133 SkTSwap(fInfo, other.fInfo); | |
| 134 SkTSwap(fRowBytes, other.fRowBytes); | 128 SkTSwap(fRowBytes, other.fRowBytes); |
| 129 SkTSwap(fWidth, other.fWidth); |
| 130 SkTSwap(fHeight, other.fHeight); |
| 131 SkTSwap(fConfig, other.fConfig); |
| 132 SkTSwap(fAlphaType, other.fAlphaType); |
| 135 SkTSwap(fFlags, other.fFlags); | 133 SkTSwap(fFlags, other.fFlags); |
| 134 SkTSwap(fBytesPerPixel, other.fBytesPerPixel); |
| 136 | 135 |
| 137 SkDEBUGCODE(this->validate();) | 136 SkDEBUGCODE(this->validate();) |
| 138 } | 137 } |
| 139 | 138 |
| 140 void SkBitmap::reset() { | 139 void SkBitmap::reset() { |
| 141 this->freePixels(); | 140 this->freePixels(); |
| 142 sk_bzero(this, sizeof(*this)); | 141 sk_bzero(this, sizeof(*this)); |
| 143 } | 142 } |
| 144 | 143 |
| 145 SkBitmap::Config SkBitmap::config() const { | |
| 146 return SkColorTypeToBitmapConfig(fInfo.colorType()); | |
| 147 } | |
| 148 | |
| 149 int SkBitmap::ComputeBytesPerPixel(SkBitmap::Config config) { | 144 int SkBitmap::ComputeBytesPerPixel(SkBitmap::Config config) { |
| 150 int bpp; | 145 int bpp; |
| 151 switch (config) { | 146 switch (config) { |
| 152 case kNo_Config: | 147 case kNo_Config: |
| 153 bpp = 0; // not applicable | 148 bpp = 0; // not applicable |
| 154 break; | 149 break; |
| 155 case kA8_Config: | 150 case kA8_Config: |
| 156 case kIndex8_Config: | 151 case kIndex8_Config: |
| 157 bpp = 1; | 152 bpp = 1; |
| 158 break; | 153 break; |
| 159 case kRGB_565_Config: | 154 case kRGB_565_Config: |
| 160 case kARGB_4444_Config: | 155 case kARGB_4444_Config: |
| 161 bpp = 2; | 156 bpp = 2; |
| 162 break; | 157 break; |
| 163 case kARGB_8888_Config: | 158 case kARGB_8888_Config: |
| 164 bpp = 4; | 159 bpp = 4; |
| 165 break; | 160 break; |
| 166 default: | 161 default: |
| 167 SkDEBUGFAIL("unknown config"); | 162 SkDEBUGFAIL("unknown config"); |
| 168 bpp = 0; // error | 163 bpp = 0; // error |
| 169 break; | 164 break; |
| 170 } | 165 } |
| 171 return bpp; | 166 return bpp; |
| 172 } | 167 } |
| 173 | 168 |
| 174 size_t SkBitmap::ComputeRowBytes(Config c, int width) { | 169 size_t SkBitmap::ComputeRowBytes(Config c, int width) { |
| 175 return SkColorTypeMinRowBytes(SkBitmapConfigToColorType(c), width); | 170 if (width < 0) { |
| 171 return 0; |
| 172 } |
| 173 |
| 174 int64_t rowBytes = 0; |
| 175 |
| 176 switch (c) { |
| 177 case kNo_Config: |
| 178 break; |
| 179 case kA8_Config: |
| 180 case kIndex8_Config: |
| 181 rowBytes = width; |
| 182 break; |
| 183 case kRGB_565_Config: |
| 184 case kARGB_4444_Config: |
| 185 // assign and then shift, so we don't overflow int |
| 186 rowBytes = width; |
| 187 rowBytes <<= 1; |
| 188 break; |
| 189 case kARGB_8888_Config: |
| 190 // assign and then shift, so we don't overflow int |
| 191 rowBytes = width; |
| 192 rowBytes <<= 2; |
| 193 break; |
| 194 default: |
| 195 SkDEBUGFAIL("unknown config"); |
| 196 break; |
| 197 } |
| 198 return sk_64_isS32(rowBytes) ? sk_64_asS32(rowBytes) : 0; |
| 176 } | 199 } |
| 177 | 200 |
| 178 int64_t SkBitmap::ComputeSize64(Config config, int width, int height) { | 201 int64_t SkBitmap::ComputeSize64(Config config, int width, int height) { |
| 179 SkColorType ct = SkBitmapConfigToColorType(config); | 202 int64_t rowBytes = sk_64_mul(ComputeBytesPerPixel(config), width); |
| 180 int64_t rowBytes = sk_64_mul(SkColorTypeBytesPerPixel(ct), width); | |
| 181 return rowBytes * height; | 203 return rowBytes * height; |
| 182 } | 204 } |
| 183 | 205 |
| 184 size_t SkBitmap::ComputeSize(Config c, int width, int height) { | 206 size_t SkBitmap::ComputeSize(Config c, int width, int height) { |
| 185 int64_t size = SkBitmap::ComputeSize64(c, width, height); | 207 int64_t size = SkBitmap::ComputeSize64(c, width, height); |
| 186 return sk_64_isS32(size) ? sk_64_asS32(size) : 0; | 208 return sk_64_isS32(size) ? sk_64_asS32(size) : 0; |
| 187 } | 209 } |
| 188 | 210 |
| 189 int64_t SkBitmap::ComputeSafeSize64(Config config, | 211 int64_t SkBitmap::ComputeSafeSize64(Config config, |
| 190 uint32_t width, | 212 uint32_t width, |
| 191 uint32_t height, | 213 uint32_t height, |
| 192 size_t rowBytes) { | 214 size_t rowBytes) { |
| 193 SkImageInfo info = SkImageInfo::Make(width, height, | 215 int64_t safeSize = 0; |
| 194 SkBitmapConfigToColorType(config), | 216 if (height > 0) { |
| 195 kPremul_SkAlphaType); | 217 int64_t lastRow = sk_64_mul(ComputeBytesPerPixel(config), width); |
| 196 return info.getSafeSize64(rowBytes); | 218 safeSize = sk_64_mul(height - 1, rowBytes) + lastRow; |
| 219 } |
| 220 SkASSERT(safeSize >= 0); |
| 221 return safeSize; |
| 197 } | 222 } |
| 198 | 223 |
| 199 size_t SkBitmap::ComputeSafeSize(Config config, | 224 size_t SkBitmap::ComputeSafeSize(Config config, |
| 200 uint32_t width, | 225 uint32_t width, |
| 201 uint32_t height, | 226 uint32_t height, |
| 202 size_t rowBytes) { | 227 size_t rowBytes) { |
| 203 int64_t safeSize = ComputeSafeSize64(config, width, height, rowBytes); | 228 int64_t safeSize = ComputeSafeSize64(config, width, height, rowBytes); |
| 204 int32_t safeSize32 = (int32_t)safeSize; | 229 int32_t safeSize32 = (int32_t)safeSize; |
| 205 | 230 |
| 206 if (safeSize32 != safeSize) { | 231 if (safeSize32 != safeSize) { |
| 207 safeSize32 = 0; | 232 safeSize32 = 0; |
| 208 } | 233 } |
| 209 return safeSize32; | 234 return safeSize32; |
| 210 } | 235 } |
| 211 | 236 |
| 212 void SkBitmap::getBounds(SkRect* bounds) const { | 237 void SkBitmap::getBounds(SkRect* bounds) const { |
| 213 SkASSERT(bounds); | 238 SkASSERT(bounds); |
| 214 bounds->set(0, 0, | 239 bounds->set(0, 0, |
| 215 SkIntToScalar(fInfo.fWidth), SkIntToScalar(fInfo.fHeight)); | 240 SkIntToScalar(fWidth), SkIntToScalar(fHeight)); |
| 216 } | 241 } |
| 217 | 242 |
| 218 void SkBitmap::getBounds(SkIRect* bounds) const { | 243 void SkBitmap::getBounds(SkIRect* bounds) const { |
| 219 SkASSERT(bounds); | 244 SkASSERT(bounds); |
| 220 bounds->set(0, 0, fInfo.fWidth, fInfo.fHeight); | 245 bounds->set(0, 0, fWidth, fHeight); |
| 221 } | 246 } |
| 222 | 247 |
| 223 /////////////////////////////////////////////////////////////////////////////// | 248 /////////////////////////////////////////////////////////////////////////////// |
| 224 | 249 |
| 225 static bool validate_alphaType(SkColorType colorType, SkAlphaType alphaType, | 250 static bool validate_alphaType(SkBitmap::Config config, SkAlphaType alphaType, |
| 226 SkAlphaType* canonical = NULL) { | 251 SkAlphaType* canonical = NULL) { |
| 227 switch (colorType) { | 252 switch (config) { |
| 228 case kUnknown_SkColorType: | 253 case SkBitmap::kNo_Config: |
| 229 alphaType = kIgnore_SkAlphaType; | 254 alphaType = kIgnore_SkAlphaType; |
| 230 break; | 255 break; |
| 231 case kAlpha_8_SkColorType: | 256 case SkBitmap::kA8_Config: |
| 232 if (kUnpremul_SkAlphaType == alphaType) { | 257 if (kUnpremul_SkAlphaType == alphaType) { |
| 233 alphaType = kPremul_SkAlphaType; | 258 alphaType = kPremul_SkAlphaType; |
| 234 } | 259 } |
| 235 // fall-through | 260 // fall-through |
| 236 case kIndex_8_SkColorType: | 261 case SkBitmap::kIndex8_Config: |
| 237 case kARGB_4444_SkColorType: | 262 case SkBitmap::kARGB_4444_Config: |
| 238 case kRGBA_8888_SkColorType: | 263 case SkBitmap::kARGB_8888_Config: |
| 239 case kBGRA_8888_SkColorType: | |
| 240 if (kIgnore_SkAlphaType == alphaType) { | 264 if (kIgnore_SkAlphaType == alphaType) { |
| 241 return false; | 265 return false; |
| 242 } | 266 } |
| 243 break; | 267 break; |
| 244 case kRGB_565_SkColorType: | 268 case SkBitmap::kRGB_565_Config: |
| 245 alphaType = kOpaque_SkAlphaType; | 269 alphaType = kOpaque_SkAlphaType; |
| 246 break; | 270 break; |
| 247 default: | 271 default: |
| 248 return false; | 272 return false; |
| 249 } | 273 } |
| 250 if (canonical) { | 274 if (canonical) { |
| 251 *canonical = alphaType; | 275 *canonical = alphaType; |
| 252 } | 276 } |
| 253 return true; | 277 return true; |
| 254 } | 278 } |
| 255 | 279 |
| 256 bool SkBitmap::setConfig(const SkImageInfo& info, size_t rowBytes) { | |
| 257 // require that rowBytes fit in 31bits | |
| 258 int64_t mrb = info.minRowBytes64(); | |
| 259 if ((int32_t)mrb != mrb) { | |
| 260 return reset_return_false(this); | |
| 261 } | |
| 262 if ((int64_t)rowBytes != (int32_t)rowBytes) { | |
| 263 return reset_return_false(this); | |
| 264 } | |
| 265 | |
| 266 if (info.width() < 0 || info.height() < 0) { | |
| 267 return reset_return_false(this); | |
| 268 } | |
| 269 | |
| 270 if (kUnknown_SkColorType == info.colorType()) { | |
| 271 rowBytes = 0; | |
| 272 } else if (0 == rowBytes) { | |
| 273 rowBytes = (size_t)mrb; | |
| 274 } else if (rowBytes < info.minRowBytes()) { | |
| 275 return reset_return_false(this); | |
| 276 } | |
| 277 | |
| 278 this->freePixels(); | |
| 279 | |
| 280 fInfo = info; | |
| 281 fRowBytes = SkToU32(rowBytes); | |
| 282 return true; | |
| 283 } | |
| 284 | |
| 285 bool SkBitmap::setConfig(Config config, int width, int height, size_t rowBytes, | 280 bool SkBitmap::setConfig(Config config, int width, int height, size_t rowBytes, |
| 286 SkAlphaType alphaType) { | 281 SkAlphaType alphaType) { |
| 287 SkColorType ct = SkBitmapConfigToColorType(config); | 282 if ((width | height) < 0) { |
| 288 return this->setConfig(SkImageInfo::Make(width, height, ct, alphaType), | 283 goto BAD_CONFIG; |
| 289 rowBytes); | 284 } |
| 285 if (rowBytes == 0) { |
| 286 rowBytes = SkBitmap::ComputeRowBytes(config, width); |
| 287 if (0 == rowBytes && kNo_Config != config && width > 0) { |
| 288 goto BAD_CONFIG; |
| 289 } |
| 290 } |
| 291 |
| 292 if (!validate_alphaType(config, alphaType, &alphaType)) { |
| 293 goto BAD_CONFIG; |
| 294 } |
| 295 |
| 296 this->freePixels(); |
| 297 |
| 298 fConfig = SkToU8(config); |
| 299 fAlphaType = SkToU8(alphaType); |
| 300 fWidth = width; |
| 301 fHeight = height; |
| 302 fRowBytes = SkToU32(rowBytes); |
| 303 |
| 304 fBytesPerPixel = (uint8_t)ComputeBytesPerPixel(config); |
| 305 |
| 306 SkDEBUGCODE(this->validate();) |
| 307 return true; |
| 308 |
| 309 // if we got here, we had an error, so we reset the bitmap to empty |
| 310 BAD_CONFIG: |
| 311 this->reset(); |
| 312 return false; |
| 313 } |
| 314 |
| 315 bool SkBitmap::setConfig(const SkImageInfo& info, size_t rowBytes) { |
| 316 return this->setConfig(SkImageInfoToBitmapConfig(info), info.fWidth, |
| 317 info.fHeight, rowBytes, info.fAlphaType); |
| 290 } | 318 } |
| 291 | 319 |
| 292 bool SkBitmap::setAlphaType(SkAlphaType alphaType) { | 320 bool SkBitmap::setAlphaType(SkAlphaType alphaType) { |
| 293 if (!validate_alphaType(fInfo.fColorType, alphaType, &alphaType)) { | 321 if (!validate_alphaType(this->config(), alphaType, &alphaType)) { |
| 294 return false; | 322 return false; |
| 295 } | 323 } |
| 296 if (fInfo.fAlphaType != alphaType) { | 324 if (fAlphaType != alphaType) { |
| 297 fInfo.fAlphaType = alphaType; | 325 fAlphaType = SkToU8(alphaType); |
| 298 if (fPixelRef) { | 326 if (fPixelRef) { |
| 299 fPixelRef->changeAlphaType(alphaType); | 327 fPixelRef->changeAlphaType(alphaType); |
| 300 } | 328 } |
| 301 } | 329 } |
| 302 return true; | 330 return true; |
| 303 } | 331 } |
| 304 | 332 |
| 305 void SkBitmap::updatePixelsFromRef() const { | 333 void SkBitmap::updatePixelsFromRef() const { |
| 306 if (NULL != fPixelRef) { | 334 if (NULL != fPixelRef) { |
| 307 if (fPixelLockCount > 0) { | 335 if (fPixelLockCount > 0) { |
| 308 SkASSERT(fPixelRef->isLocked()); | 336 SkASSERT(fPixelRef->isLocked()); |
| 309 | 337 |
| 310 void* p = fPixelRef->pixels(); | 338 void* p = fPixelRef->pixels(); |
| 311 if (NULL != p) { | 339 if (NULL != p) { |
| 312 p = (char*)p | 340 p = (char*)p |
| 313 + fPixelRefOrigin.fY * fRowBytes | 341 + fPixelRefOrigin.fY * fRowBytes |
| 314 + fPixelRefOrigin.fX * fInfo.bytesPerPixel(); | 342 + fPixelRefOrigin.fX * fBytesPerPixel; |
| 315 } | 343 } |
| 316 fPixels = p; | 344 fPixels = p; |
| 317 fColorTable = fPixelRef->colorTable(); | 345 fColorTable = fPixelRef->colorTable(); |
| 318 } else { | 346 } else { |
| 319 SkASSERT(0 == fPixelLockCount); | 347 SkASSERT(0 == fPixelLockCount); |
| 320 fPixels = NULL; | 348 fPixels = NULL; |
| 321 fColorTable = NULL; | 349 fColorTable = NULL; |
| 322 } | 350 } |
| 323 } | 351 } |
| 324 } | 352 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 344 case SkBitmap::kNo_Config: | 372 case SkBitmap::kNo_Config: |
| 345 default: | 373 default: |
| 346 return false; | 374 return false; |
| 347 } | 375 } |
| 348 if (ctOut) { | 376 if (ctOut) { |
| 349 *ctOut = ct; | 377 *ctOut = ct; |
| 350 } | 378 } |
| 351 return true; | 379 return true; |
| 352 } | 380 } |
| 353 | 381 |
| 382 bool SkBitmap::asImageInfo(SkImageInfo* info) const { |
| 383 SkColorType ct; |
| 384 if (!config_to_colorType(this->config(), &ct)) { |
| 385 return false; |
| 386 } |
| 387 if (info) { |
| 388 info->fWidth = fWidth; |
| 389 info->fHeight = fHeight; |
| 390 info->fAlphaType = this->alphaType(); |
| 391 info->fColorType = ct; |
| 392 } |
| 393 return true; |
| 394 } |
| 395 |
| 354 SkPixelRef* SkBitmap::setPixelRef(SkPixelRef* pr, int dx, int dy) { | 396 SkPixelRef* SkBitmap::setPixelRef(SkPixelRef* pr, int dx, int dy) { |
| 355 #ifdef SK_DEBUG | 397 #ifdef SK_DEBUG |
| 356 if (pr) { | 398 if (pr) { |
| 357 SkImageInfo info; | 399 SkImageInfo info; |
| 358 if (this->asImageInfo(&info)) { | 400 if (this->asImageInfo(&info)) { |
| 359 const SkImageInfo& prInfo = pr->info(); | 401 const SkImageInfo& prInfo = pr->info(); |
| 360 SkASSERT(info.fWidth <= prInfo.fWidth); | 402 SkASSERT(info.fWidth <= prInfo.fWidth); |
| 361 SkASSERT(info.fHeight <= prInfo.fHeight); | 403 SkASSERT(info.fHeight <= prInfo.fHeight); |
| 362 SkASSERT(info.fColorType == prInfo.fColorType); | 404 SkASSERT(info.fColorType == prInfo.fColorType); |
| 363 switch (prInfo.fAlphaType) { | 405 switch (prInfo.fAlphaType) { |
| 364 case kIgnore_SkAlphaType: | 406 case kIgnore_SkAlphaType: |
| 365 SkASSERT(fInfo.fAlphaType == kIgnore_SkAlphaType); | 407 SkASSERT(fAlphaType == kIgnore_SkAlphaType); |
| 366 break; | 408 break; |
| 367 case kOpaque_SkAlphaType: | 409 case kOpaque_SkAlphaType: |
| 368 case kPremul_SkAlphaType: | 410 case kPremul_SkAlphaType: |
| 369 SkASSERT(info.fAlphaType == kOpaque_SkAlphaType || | 411 SkASSERT(info.fAlphaType == kOpaque_SkAlphaType || |
| 370 info.fAlphaType == kPremul_SkAlphaType); | 412 info.fAlphaType == kPremul_SkAlphaType); |
| 371 break; | 413 break; |
| 372 case kUnpremul_SkAlphaType: | 414 case kUnpremul_SkAlphaType: |
| 373 SkASSERT(info.fAlphaType == kOpaque_SkAlphaType || | 415 SkASSERT(info.fAlphaType == kOpaque_SkAlphaType || |
| 374 info.fAlphaType == kUnpremul_SkAlphaType); | 416 info.fAlphaType == kUnpremul_SkAlphaType); |
| 375 break; | 417 break; |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 453 HeapAllocator stdalloc; | 495 HeapAllocator stdalloc; |
| 454 | 496 |
| 455 if (NULL == allocator) { | 497 if (NULL == allocator) { |
| 456 allocator = &stdalloc; | 498 allocator = &stdalloc; |
| 457 } | 499 } |
| 458 return allocator->allocPixelRef(this, ctable); | 500 return allocator->allocPixelRef(this, ctable); |
| 459 } | 501 } |
| 460 | 502 |
| 461 /////////////////////////////////////////////////////////////////////////////// | 503 /////////////////////////////////////////////////////////////////////////////// |
| 462 | 504 |
| 505 static bool reset_return_false(SkBitmap* bm) { |
| 506 bm->reset(); |
| 507 return false; |
| 508 } |
| 509 |
| 463 bool SkBitmap::allocPixels(const SkImageInfo& info, SkPixelRefFactory* factory, | 510 bool SkBitmap::allocPixels(const SkImageInfo& info, SkPixelRefFactory* factory, |
| 464 SkColorTable* ctable) { | 511 SkColorTable* ctable) { |
| 465 if (kIndex_8_SkColorType == info.fColorType && NULL == ctable) { | 512 if (kIndex_8_SkColorType == info.fColorType && NULL == ctable) { |
| 466 return reset_return_false(this); | 513 return reset_return_false(this); |
| 467 } | 514 } |
| 468 if (!this->setConfig(info)) { | 515 if (!this->setConfig(info)) { |
| 469 return reset_return_false(this); | 516 return reset_return_false(this); |
| 470 } | 517 } |
| 471 | 518 |
| 472 SkMallocPixelRef::PRFactory defaultFactory; | 519 SkMallocPixelRef::PRFactory defaultFactory; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 508 } | 555 } |
| 509 | 556 |
| 510 bool SkBitmap::allocConfigPixels(Config config, int width, int height, | 557 bool SkBitmap::allocConfigPixels(Config config, int width, int height, |
| 511 bool isOpaque) { | 558 bool isOpaque) { |
| 512 SkColorType ct; | 559 SkColorType ct; |
| 513 if (!config_to_colorType(config, &ct)) { | 560 if (!config_to_colorType(config, &ct)) { |
| 514 return false; | 561 return false; |
| 515 } | 562 } |
| 516 | 563 |
| 517 SkAlphaType at = isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType; | 564 SkAlphaType at = isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType; |
| 565 if (!validate_alphaType(config, at, &at)) { |
| 566 return false; |
| 567 } |
| 568 |
| 518 return this->allocPixels(SkImageInfo::Make(width, height, ct, at)); | 569 return this->allocPixels(SkImageInfo::Make(width, height, ct, at)); |
| 519 } | 570 } |
| 520 | 571 |
| 521 /////////////////////////////////////////////////////////////////////////////// | 572 /////////////////////////////////////////////////////////////////////////////// |
| 522 | 573 |
| 523 void SkBitmap::freePixels() { | 574 void SkBitmap::freePixels() { |
| 524 // if we're gonna free the pixels, we certainly need to free the mipmap | 575 // if we're gonna free the pixels, we certainly need to free the mipmap |
| 525 this->freeMipMap(); | 576 this->freeMipMap(); |
| 526 | 577 |
| 527 if (NULL != fPixelRef) { | 578 if (NULL != fPixelRef) { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 579 } | 630 } |
| 580 | 631 |
| 581 dst->setPixelRef(pr)->unref(); | 632 dst->setPixelRef(pr)->unref(); |
| 582 // since we're already allocated, we lockPixels right away | 633 // since we're already allocated, we lockPixels right away |
| 583 dst->lockPixels(); | 634 dst->lockPixels(); |
| 584 return true; | 635 return true; |
| 585 } | 636 } |
| 586 | 637 |
| 587 /////////////////////////////////////////////////////////////////////////////// | 638 /////////////////////////////////////////////////////////////////////////////// |
| 588 | 639 |
| 640 size_t SkBitmap::getSafeSize() const { |
| 641 // This is intended to be a size_t version of ComputeSafeSize64(), just |
| 642 // faster. The computation is meant to be identical. |
| 643 return (fHeight ? ((fHeight - 1) * fRowBytes) + |
| 644 ComputeRowBytes(this->config(), fWidth): 0); |
| 645 } |
| 646 |
| 589 bool SkBitmap::copyPixelsTo(void* const dst, size_t dstSize, | 647 bool SkBitmap::copyPixelsTo(void* const dst, size_t dstSize, |
| 590 size_t dstRowBytes, bool preserveDstPad) const { | 648 size_t dstRowBytes, bool preserveDstPad) const { |
| 591 | 649 |
| 592 if (0 == dstRowBytes) { | 650 if (0 == dstRowBytes) { |
| 593 dstRowBytes = fRowBytes; | 651 dstRowBytes = fRowBytes; |
| 594 } | 652 } |
| 595 | 653 |
| 596 if (dstRowBytes < fInfo.minRowBytes() || | 654 if (dstRowBytes < ComputeRowBytes(this->config(), fWidth) || |
| 597 dst == NULL || (getPixels() == NULL && pixelRef() == NULL)) { | 655 dst == NULL || (getPixels() == NULL && pixelRef() == NULL)) |
| 598 return false; | 656 return false; |
| 599 } | |
| 600 | 657 |
| 601 if (!preserveDstPad && static_cast<uint32_t>(dstRowBytes) == fRowBytes) { | 658 if (!preserveDstPad && static_cast<uint32_t>(dstRowBytes) == fRowBytes) { |
| 602 size_t safeSize = this->getSafeSize(); | 659 size_t safeSize = this->getSafeSize(); |
| 603 if (safeSize > dstSize || safeSize == 0) | 660 if (safeSize > dstSize || safeSize == 0) |
| 604 return false; | 661 return false; |
| 605 else { | 662 else { |
| 606 SkAutoLockPixels lock(*this); | 663 SkAutoLockPixels lock(*this); |
| 607 // This implementation will write bytes beyond the end of each row, | 664 // This implementation will write bytes beyond the end of each row, |
| 608 // excluding the last row, if the bitmap's stride is greater than | 665 // excluding the last row, if the bitmap's stride is greater than |
| 609 // strictly required by the current config. | 666 // strictly required by the current config. |
| 610 memcpy(dst, getPixels(), safeSize); | 667 memcpy(dst, getPixels(), safeSize); |
| 611 | 668 |
| 612 return true; | 669 return true; |
| 613 } | 670 } |
| 614 } else { | 671 } else { |
| 615 // If destination has different stride than us, then copy line by line. | 672 // If destination has different stride than us, then copy line by line. |
| 616 if (fInfo.getSafeSize(dstRowBytes) > dstSize) { | 673 if (ComputeSafeSize(this->config(), fWidth, fHeight, dstRowBytes) > |
| 674 dstSize) |
| 617 return false; | 675 return false; |
| 618 } else { | 676 else { |
| 619 // Just copy what we need on each line. | 677 // Just copy what we need on each line. |
| 620 size_t rowBytes = fInfo.minRowBytes(); | 678 size_t rowBytes = ComputeRowBytes(this->config(), fWidth); |
| 621 SkAutoLockPixels lock(*this); | 679 SkAutoLockPixels lock(*this); |
| 622 const uint8_t* srcP = reinterpret_cast<const uint8_t*>(getPixels()); | 680 const uint8_t* srcP = reinterpret_cast<const uint8_t*>(getPixels()); |
| 623 uint8_t* dstP = reinterpret_cast<uint8_t*>(dst); | 681 uint8_t* dstP = reinterpret_cast<uint8_t*>(dst); |
| 624 for (int row = 0; row < fInfo.fHeight; | 682 for (uint32_t row = 0; row < fHeight; |
| 625 row++, srcP += fRowBytes, dstP += dstRowBytes) { | 683 row++, srcP += fRowBytes, dstP += dstRowBytes) { |
| 626 memcpy(dstP, srcP, rowBytes); | 684 memcpy(dstP, srcP, rowBytes); |
| 627 } | 685 } |
| 628 | 686 |
| 629 return true; | 687 return true; |
| 630 } | 688 } |
| 631 } | 689 } |
| 632 } | 690 } |
| 633 | 691 |
| 634 /////////////////////////////////////////////////////////////////////////////// | 692 /////////////////////////////////////////////////////////////////////////////// |
| (...skipping 23 matching lines...) Expand all Loading... |
| 658 } | 716 } |
| 659 } | 717 } |
| 660 | 718 |
| 661 void* SkBitmap::getAddr(int x, int y) const { | 719 void* SkBitmap::getAddr(int x, int y) const { |
| 662 SkASSERT((unsigned)x < (unsigned)this->width()); | 720 SkASSERT((unsigned)x < (unsigned)this->width()); |
| 663 SkASSERT((unsigned)y < (unsigned)this->height()); | 721 SkASSERT((unsigned)y < (unsigned)this->height()); |
| 664 | 722 |
| 665 char* base = (char*)this->getPixels(); | 723 char* base = (char*)this->getPixels(); |
| 666 if (base) { | 724 if (base) { |
| 667 base += y * this->rowBytes(); | 725 base += y * this->rowBytes(); |
| 668 switch (this->colorType()) { | 726 switch (this->config()) { |
| 669 case kRGBA_8888_SkColorType: | 727 case SkBitmap::kARGB_8888_Config: |
| 670 case kBGRA_8888_SkColorType: | |
| 671 base += x << 2; | 728 base += x << 2; |
| 672 break; | 729 break; |
| 673 case kARGB_4444_SkColorType: | 730 case SkBitmap::kARGB_4444_Config: |
| 674 case kRGB_565_SkColorType: | 731 case SkBitmap::kRGB_565_Config: |
| 675 base += x << 1; | 732 base += x << 1; |
| 676 break; | 733 break; |
| 677 case kAlpha_8_SkColorType: | 734 case SkBitmap::kA8_Config: |
| 678 case kIndex_8_SkColorType: | 735 case SkBitmap::kIndex8_Config: |
| 679 base += x; | 736 base += x; |
| 680 break; | 737 break; |
| 738 break; |
| 681 default: | 739 default: |
| 682 SkDEBUGFAIL("Can't return addr for config"); | 740 SkDEBUGFAIL("Can't return addr for config"); |
| 683 base = NULL; | 741 base = NULL; |
| 684 break; | 742 break; |
| 685 } | 743 } |
| 686 } | 744 } |
| 687 return base; | 745 return base; |
| 688 } | 746 } |
| 689 | 747 |
| 690 SkColor SkBitmap::getColor(int x, int y) const { | 748 SkColor SkBitmap::getColor(int x, int y) const { |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 808 U8CPU a, U8CPU r, U8CPU g, U8CPU b) const { | 866 U8CPU a, U8CPU r, U8CPU g, U8CPU b) const { |
| 809 #ifdef SK_DEBUG | 867 #ifdef SK_DEBUG |
| 810 SkDEBUGCODE(this->validate();) | 868 SkDEBUGCODE(this->validate();) |
| 811 SkASSERT(!area.isEmpty()); | 869 SkASSERT(!area.isEmpty()); |
| 812 { | 870 { |
| 813 SkIRect total = { 0, 0, this->width(), this->height() }; | 871 SkIRect total = { 0, 0, this->width(), this->height() }; |
| 814 SkASSERT(total.contains(area)); | 872 SkASSERT(total.contains(area)); |
| 815 } | 873 } |
| 816 #endif | 874 #endif |
| 817 | 875 |
| 818 switch (fInfo.colorType()) { | 876 if (kNo_Config == fConfig || kIndex8_Config == fConfig) { |
| 819 case kUnknown_SkColorType: | 877 return; |
| 820 case kIndex_8_SkColorType: | |
| 821 return; // can't erase | |
| 822 default: | |
| 823 break; | |
| 824 } | 878 } |
| 825 | 879 |
| 826 SkAutoLockPixels alp(*this); | 880 SkAutoLockPixels alp(*this); |
| 827 // perform this check after the lock call | 881 // perform this check after the lock call |
| 828 if (!this->readyToDraw()) { | 882 if (!this->readyToDraw()) { |
| 829 return; | 883 return; |
| 830 } | 884 } |
| 831 | 885 |
| 832 int height = area.height(); | 886 int height = area.height(); |
| 833 const int width = area.width(); | 887 const int width = area.width(); |
| 834 const int rowBytes = fRowBytes; | 888 const int rowBytes = fRowBytes; |
| 835 | 889 |
| 836 // make rgb premultiplied | 890 // make rgb premultiplied |
| 837 if (255 != a) { | 891 if (255 != a) { |
| 838 r = SkAlphaMul(r, a); | 892 r = SkAlphaMul(r, a); |
| 839 g = SkAlphaMul(g, a); | 893 g = SkAlphaMul(g, a); |
| 840 b = SkAlphaMul(b, a); | 894 b = SkAlphaMul(b, a); |
| 841 } | 895 } |
| 842 | 896 |
| 843 switch (this->colorType()) { | 897 switch (fConfig) { |
| 844 case kAlpha_8_SkColorType: { | 898 case kA8_Config: { |
| 845 uint8_t* p = this->getAddr8(area.fLeft, area.fTop); | 899 uint8_t* p = this->getAddr8(area.fLeft, area.fTop); |
| 846 while (--height >= 0) { | 900 while (--height >= 0) { |
| 847 memset(p, a, width); | 901 memset(p, a, width); |
| 848 p += rowBytes; | 902 p += rowBytes; |
| 849 } | 903 } |
| 850 break; | 904 break; |
| 851 } | 905 } |
| 852 case kARGB_4444_SkColorType: | 906 case kARGB_4444_Config: |
| 853 case kRGB_565_SkColorType: { | 907 case kRGB_565_Config: { |
| 854 uint16_t* p = this->getAddr16(area.fLeft, area.fTop);; | 908 uint16_t* p = this->getAddr16(area.fLeft, area.fTop);; |
| 855 uint16_t v; | 909 uint16_t v; |
| 856 | 910 |
| 857 if (kARGB_4444_SkColorType == this->colorType()) { | 911 if (kARGB_4444_Config == fConfig) { |
| 858 v = pack_8888_to_4444(a, r, g, b); | 912 v = pack_8888_to_4444(a, r, g, b); |
| 859 } else { | 913 } else { |
| 860 v = SkPackRGB16(r >> (8 - SK_R16_BITS), | 914 v = SkPackRGB16(r >> (8 - SK_R16_BITS), |
| 861 g >> (8 - SK_G16_BITS), | 915 g >> (8 - SK_G16_BITS), |
| 862 b >> (8 - SK_B16_BITS)); | 916 b >> (8 - SK_B16_BITS)); |
| 863 } | 917 } |
| 864 while (--height >= 0) { | 918 while (--height >= 0) { |
| 865 sk_memset16(p, v, width); | 919 sk_memset16(p, v, width); |
| 866 p = (uint16_t*)((char*)p + rowBytes); | 920 p = (uint16_t*)((char*)p + rowBytes); |
| 867 } | 921 } |
| 868 break; | 922 break; |
| 869 } | 923 } |
| 870 case kPMColor_SkColorType: { | 924 case kARGB_8888_Config: { |
| 871 // what to do about BGRA or RGBA (which ever is != PMColor ? | |
| 872 // for now we don't support them. | |
| 873 uint32_t* p = this->getAddr32(area.fLeft, area.fTop); | 925 uint32_t* p = this->getAddr32(area.fLeft, area.fTop); |
| 874 uint32_t v = SkPackARGB32(a, r, g, b); | 926 uint32_t v = SkPackARGB32(a, r, g, b); |
| 875 | 927 |
| 876 while (--height >= 0) { | 928 while (--height >= 0) { |
| 877 sk_memset32(p, v, width); | 929 sk_memset32(p, v, width); |
| 878 p = (uint32_t*)((char*)p + rowBytes); | 930 p = (uint32_t*)((char*)p + rowBytes); |
| 879 } | 931 } |
| 880 break; | 932 break; |
| 881 } | 933 } |
| 882 default: | |
| 883 return; // no change, so don't call notifyPixelsChanged() | |
| 884 } | 934 } |
| 885 | 935 |
| 886 this->notifyPixelsChanged(); | 936 this->notifyPixelsChanged(); |
| 887 } | 937 } |
| 888 | 938 |
| 889 void SkBitmap::eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) const { | 939 void SkBitmap::eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) const { |
| 890 SkIRect area = { 0, 0, this->width(), this->height() }; | 940 SkIRect area = { 0, 0, this->width(), this->height() }; |
| 891 if (!area.isEmpty()) { | 941 if (!area.isEmpty()) { |
| 892 this->internalErase(area, a, r, g, b); | 942 this->internalErase(area, a, r, g, b); |
| 893 } | 943 } |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 989 if (!this->canCopyTo(dstConfig)) { | 1039 if (!this->canCopyTo(dstConfig)) { |
| 990 return false; | 1040 return false; |
| 991 } | 1041 } |
| 992 | 1042 |
| 993 // if we have a texture, first get those pixels | 1043 // if we have a texture, first get those pixels |
| 994 SkBitmap tmpSrc; | 1044 SkBitmap tmpSrc; |
| 995 const SkBitmap* src = this; | 1045 const SkBitmap* src = this; |
| 996 | 1046 |
| 997 if (fPixelRef) { | 1047 if (fPixelRef) { |
| 998 SkIRect subset; | 1048 SkIRect subset; |
| 999 subset.setXYWH(fPixelRefOrigin.fX, fPixelRefOrigin.fY, | 1049 subset.setXYWH(fPixelRefOrigin.fX, fPixelRefOrigin.fY, fWidth, fHeight); |
| 1000 fInfo.width(), fInfo.height()); | |
| 1001 if (fPixelRef->readPixels(&tmpSrc, &subset)) { | 1050 if (fPixelRef->readPixels(&tmpSrc, &subset)) { |
| 1002 SkASSERT(tmpSrc.width() == this->width()); | 1051 SkASSERT(tmpSrc.width() == this->width()); |
| 1003 SkASSERT(tmpSrc.height() == this->height()); | 1052 SkASSERT(tmpSrc.height() == this->height()); |
| 1004 | 1053 |
| 1005 // did we get lucky and we can just return tmpSrc? | 1054 // did we get lucky and we can just return tmpSrc? |
| 1006 if (tmpSrc.config() == dstConfig && NULL == alloc) { | 1055 if (tmpSrc.config() == dstConfig && NULL == alloc) { |
| 1007 dst->swap(tmpSrc); | 1056 dst->swap(tmpSrc); |
| 1008 // If the result is an exact copy, clone the gen ID. | 1057 // If the result is an exact copy, clone the gen ID. |
| 1009 if (dst->pixelRef() && dst->pixelRef()->info() == fPixelRef->inf
o()) { | 1058 if (dst->pixelRef() && dst->pixelRef()->info() == fPixelRef->inf
o()) { |
| 1010 dst->pixelRef()->cloneGenID(*fPixelRef); | 1059 dst->pixelRef()->cloneGenID(*fPixelRef); |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1104 | 1153 |
| 1105 paint.setDither(true); | 1154 paint.setDither(true); |
| 1106 canvas.drawBitmap(*src, 0, 0, &paint); | 1155 canvas.drawBitmap(*src, 0, 0, &paint); |
| 1107 } | 1156 } |
| 1108 | 1157 |
| 1109 dst->swap(tmpDst); | 1158 dst->swap(tmpDst); |
| 1110 return true; | 1159 return true; |
| 1111 } | 1160 } |
| 1112 | 1161 |
| 1113 bool SkBitmap::deepCopyTo(SkBitmap* dst, Config dstConfig) const { | 1162 bool SkBitmap::deepCopyTo(SkBitmap* dst, Config dstConfig) const { |
| 1114 const SkColorType dstCT = SkBitmapConfigToColorType(dstConfig); | |
| 1115 | |
| 1116 if (!this->canCopyTo(dstConfig)) { | 1163 if (!this->canCopyTo(dstConfig)) { |
| 1117 return false; | 1164 return false; |
| 1118 } | 1165 } |
| 1119 | 1166 |
| 1120 // If we have a PixelRef, and it supports deep copy, use it. | 1167 // If we have a PixelRef, and it supports deep copy, use it. |
| 1121 // Currently supported only by texture-backed bitmaps. | 1168 // Currently supported only by texture-backed bitmaps. |
| 1122 if (fPixelRef) { | 1169 if (fPixelRef) { |
| 1123 SkPixelRef* pixelRef = fPixelRef->deepCopy(dstConfig); | 1170 SkPixelRef* pixelRef = fPixelRef->deepCopy(dstConfig); |
| 1124 if (pixelRef) { | 1171 if (pixelRef) { |
| 1125 uint32_t rowBytes; | 1172 uint32_t rowBytes; |
| 1126 if (this->colorType() == dstCT) { | 1173 if (dstConfig == fConfig) { |
| 1127 // Since there is no subset to pass to deepCopy, and deepCopy | 1174 // Since there is no subset to pass to deepCopy, and deepCopy |
| 1128 // succeeded, the new pixel ref must be identical. | 1175 // succeeded, the new pixel ref must be identical. |
| 1129 SkASSERT(fPixelRef->info() == pixelRef->info()); | 1176 SkASSERT(fPixelRef->info() == pixelRef->info()); |
| 1130 pixelRef->cloneGenID(*fPixelRef); | 1177 pixelRef->cloneGenID(*fPixelRef); |
| 1131 // Use the same rowBytes as the original. | 1178 // Use the same rowBytes as the original. |
| 1132 rowBytes = fRowBytes; | 1179 rowBytes = fRowBytes; |
| 1133 } else { | 1180 } else { |
| 1134 // With the new config, an appropriate fRowBytes will be compute
d by setConfig. | 1181 // With the new config, an appropriate fRowBytes will be compute
d by setConfig. |
| 1135 rowBytes = 0; | 1182 rowBytes = 0; |
| 1136 } | 1183 } |
| 1137 | 1184 dst->setConfig(dstConfig, fWidth, fHeight, rowBytes); |
| 1138 SkImageInfo info = fInfo; | |
| 1139 info.fColorType = dstCT; | |
| 1140 if (!dst->setConfig(info, rowBytes)) { | |
| 1141 return false; | |
| 1142 } | |
| 1143 dst->setPixelRef(pixelRef, fPixelRefOrigin)->unref(); | 1185 dst->setPixelRef(pixelRef, fPixelRefOrigin)->unref(); |
| 1144 return true; | 1186 return true; |
| 1145 } | 1187 } |
| 1146 } | 1188 } |
| 1147 | 1189 |
| 1148 if (this->getTexture()) { | 1190 if (this->getTexture()) { |
| 1149 return false; | 1191 return false; |
| 1150 } else { | 1192 } else { |
| 1151 return this->copyTo(dst, dstConfig, NULL); | 1193 return this->copyTo(dst, dstConfig, NULL); |
| 1152 } | 1194 } |
| (...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1535 } | 1577 } |
| 1536 | 1578 |
| 1537 /////////////////////////////////////////////////////////////////////////////// | 1579 /////////////////////////////////////////////////////////////////////////////// |
| 1538 | 1580 |
| 1539 enum { | 1581 enum { |
| 1540 SERIALIZE_PIXELTYPE_NONE, | 1582 SERIALIZE_PIXELTYPE_NONE, |
| 1541 SERIALIZE_PIXELTYPE_REF_DATA | 1583 SERIALIZE_PIXELTYPE_REF_DATA |
| 1542 }; | 1584 }; |
| 1543 | 1585 |
| 1544 void SkBitmap::flatten(SkWriteBuffer& buffer) const { | 1586 void SkBitmap::flatten(SkWriteBuffer& buffer) const { |
| 1545 fInfo.flatten(buffer); | 1587 buffer.writeInt(fWidth); |
| 1588 buffer.writeInt(fHeight); |
| 1546 buffer.writeInt(fRowBytes); | 1589 buffer.writeInt(fRowBytes); |
| 1590 buffer.writeInt(fConfig); |
| 1591 buffer.writeInt(fAlphaType); |
| 1547 | 1592 |
| 1548 if (fPixelRef) { | 1593 if (fPixelRef) { |
| 1549 if (fPixelRef->getFactory()) { | 1594 if (fPixelRef->getFactory()) { |
| 1550 buffer.writeInt(SERIALIZE_PIXELTYPE_REF_DATA); | 1595 buffer.writeInt(SERIALIZE_PIXELTYPE_REF_DATA); |
| 1551 buffer.writeInt(fPixelRefOrigin.fX); | 1596 buffer.writeInt(fPixelRefOrigin.fX); |
| 1552 buffer.writeInt(fPixelRefOrigin.fY); | 1597 buffer.writeInt(fPixelRefOrigin.fY); |
| 1553 buffer.writeFlattenable(fPixelRef); | 1598 buffer.writeFlattenable(fPixelRef); |
| 1554 return; | 1599 return; |
| 1555 } | 1600 } |
| 1556 // if we get here, we can't record the pixels | 1601 // if we get here, we can't record the pixels |
| 1557 buffer.writeInt(SERIALIZE_PIXELTYPE_NONE); | 1602 buffer.writeInt(SERIALIZE_PIXELTYPE_NONE); |
| 1558 } else { | 1603 } else { |
| 1559 buffer.writeInt(SERIALIZE_PIXELTYPE_NONE); | 1604 buffer.writeInt(SERIALIZE_PIXELTYPE_NONE); |
| 1560 } | 1605 } |
| 1561 } | 1606 } |
| 1562 | 1607 |
| 1563 void SkBitmap::unflatten(SkReadBuffer& buffer) { | 1608 void SkBitmap::unflatten(SkReadBuffer& buffer) { |
| 1564 this->reset(); | 1609 this->reset(); |
| 1565 | 1610 |
| 1566 SkImageInfo info; | 1611 int width = buffer.readInt(); |
| 1567 info.unflatten(buffer); | 1612 int height = buffer.readInt(); |
| 1568 size_t rowBytes = buffer.readInt(); | 1613 int rowBytes = buffer.readInt(); |
| 1569 buffer.validate((info.width() >= 0) && (info.height() >= 0) && | 1614 Config config = (Config)buffer.readInt(); |
| 1570 SkColorTypeIsValid(info.fColorType) && | 1615 SkAlphaType alphaType = (SkAlphaType)buffer.readInt(); |
| 1571 SkAlphaTypeIsValid(info.fAlphaType) && | 1616 buffer.validate((width >= 0) && (height >= 0) && (rowBytes >= 0) && |
| 1572 validate_alphaType(info.fColorType, info.fAlphaType) && | 1617 SkIsValidConfig(config) && validate_alphaType(config, alphaT
ype)); |
| 1573 info.validRowBytes(rowBytes)); | |
| 1574 | 1618 |
| 1575 bool configIsValid = this->setConfig(info, rowBytes); | 1619 bool configIsValid = this->setConfig(config, width, height, rowBytes, alphaT
ype); |
| 1576 buffer.validate(configIsValid); | 1620 // Note : Using (fRowBytes >= (fWidth * fBytesPerPixel)) in the following te
st can create false |
| 1621 // positives if the multiplication causes an integer overflow. Use th
e division instead. |
| 1622 buffer.validate(configIsValid && (fBytesPerPixel > 0) && |
| 1623 ((fRowBytes / fBytesPerPixel) >= fWidth)); |
| 1577 | 1624 |
| 1578 int reftype = buffer.readInt(); | 1625 int reftype = buffer.readInt(); |
| 1579 if (buffer.validate((SERIALIZE_PIXELTYPE_REF_DATA == reftype) || | 1626 if (buffer.validate((SERIALIZE_PIXELTYPE_REF_DATA == reftype) || |
| 1580 (SERIALIZE_PIXELTYPE_NONE == reftype))) { | 1627 (SERIALIZE_PIXELTYPE_NONE == reftype))) { |
| 1581 switch (reftype) { | 1628 switch (reftype) { |
| 1582 case SERIALIZE_PIXELTYPE_REF_DATA: { | 1629 case SERIALIZE_PIXELTYPE_REF_DATA: { |
| 1583 SkIPoint origin; | 1630 SkIPoint origin; |
| 1584 origin.fX = buffer.readInt(); | 1631 origin.fX = buffer.readInt(); |
| 1585 origin.fY = buffer.readInt(); | 1632 origin.fY = buffer.readInt(); |
| 1586 size_t offset = origin.fY * rowBytes + origin.fX * info.bytesPer
Pixel(); | 1633 size_t offset = origin.fY * rowBytes + origin.fX * fBytesPerPixe
l; |
| 1587 SkPixelRef* pr = buffer.readPixelRef(); | 1634 SkPixelRef* pr = buffer.readPixelRef(); |
| 1588 if (!buffer.validate((NULL == pr) || | 1635 if (!buffer.validate((NULL == pr) || |
| 1589 (pr->getAllocatedSizeInBytes() >= (offset + this->getSafe
Size())))) { | 1636 (pr->getAllocatedSizeInBytes() >= (offset + this->getSafe
Size())))) { |
| 1590 origin.setZero(); | 1637 origin.setZero(); |
| 1591 } | 1638 } |
| 1592 SkSafeUnref(this->setPixelRef(pr, origin)); | 1639 SkSafeUnref(this->setPixelRef(pr, origin)); |
| 1593 break; | 1640 break; |
| 1594 } | 1641 } |
| 1595 case SERIALIZE_PIXELTYPE_NONE: | 1642 case SERIALIZE_PIXELTYPE_NONE: |
| 1596 break; | 1643 break; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1609 } | 1656 } |
| 1610 | 1657 |
| 1611 SkBitmap::RLEPixels::~RLEPixels() { | 1658 SkBitmap::RLEPixels::~RLEPixels() { |
| 1612 sk_free(fYPtrs); | 1659 sk_free(fYPtrs); |
| 1613 } | 1660 } |
| 1614 | 1661 |
| 1615 /////////////////////////////////////////////////////////////////////////////// | 1662 /////////////////////////////////////////////////////////////////////////////// |
| 1616 | 1663 |
| 1617 #ifdef SK_DEBUG | 1664 #ifdef SK_DEBUG |
| 1618 void SkBitmap::validate() const { | 1665 void SkBitmap::validate() const { |
| 1619 fInfo.validate(); | 1666 SkASSERT(fConfig < kConfigCount); |
| 1620 SkASSERT(fInfo.validRowBytes(fRowBytes)); | 1667 SkASSERT(fRowBytes >= (unsigned)ComputeRowBytes((Config)fConfig, fWidth)); |
| 1621 uint8_t allFlags = kImageIsOpaque_Flag | kImageIsVolatile_Flag | kImageIsImm
utable_Flag; | 1668 uint8_t allFlags = kImageIsOpaque_Flag | kImageIsVolatile_Flag | kImageIsImm
utable_Flag; |
| 1622 #ifdef SK_BUILD_FOR_ANDROID | 1669 #ifdef SK_BUILD_FOR_ANDROID |
| 1623 allFlags |= kHasHardwareMipMap_Flag; | 1670 allFlags |= kHasHardwareMipMap_Flag; |
| 1624 #endif | 1671 #endif |
| 1625 SkASSERT(fFlags <= allFlags); | 1672 SkASSERT(fFlags <= allFlags); |
| 1626 SkASSERT(fPixelLockCount >= 0); | 1673 SkASSERT(fPixelLockCount >= 0); |
| 1674 SkASSERT((uint8_t)ComputeBytesPerPixel((Config)fConfig) == fBytesPerPixel); |
| 1627 | 1675 |
| 1628 if (fPixels) { | 1676 if (fPixels) { |
| 1629 SkASSERT(fPixelRef); | 1677 SkASSERT(fPixelRef); |
| 1630 SkASSERT(fPixelLockCount > 0); | 1678 SkASSERT(fPixelLockCount > 0); |
| 1631 SkASSERT(fPixelRef->isLocked()); | 1679 SkASSERT(fPixelRef->isLocked()); |
| 1632 SkASSERT(fPixelRef->rowBytes() == fRowBytes); | 1680 SkASSERT(fPixelRef->rowBytes() == fRowBytes); |
| 1633 SkASSERT(fPixelRefOrigin.fX >= 0); | 1681 SkASSERT(fPixelRefOrigin.fX >= 0); |
| 1634 SkASSERT(fPixelRefOrigin.fY >= 0); | 1682 SkASSERT(fPixelRefOrigin.fY >= 0); |
| 1635 SkASSERT(fPixelRef->info().width() >= (int)this->width() + fPixelRefOrig
in.fX); | 1683 SkASSERT(fPixelRef->info().fWidth >= (int)fWidth + fPixelRefOrigin.fX); |
| 1636 SkASSERT(fPixelRef->info().fHeight >= (int)this->height() + fPixelRefOri
gin.fY); | 1684 SkASSERT(fPixelRef->info().fHeight >= (int)fHeight + fPixelRefOrigin.fY)
; |
| 1637 SkASSERT(fPixelRef->rowBytes() >= fInfo.minRowBytes()); | 1685 SkASSERT(fPixelRef->rowBytes() >= fWidth * fBytesPerPixel); |
| 1638 } else { | 1686 } else { |
| 1639 SkASSERT(NULL == fColorTable); | 1687 SkASSERT(NULL == fColorTable); |
| 1640 } | 1688 } |
| 1641 } | 1689 } |
| 1642 #endif | 1690 #endif |
| 1643 | 1691 |
| 1644 #ifdef SK_DEVELOPER | 1692 #ifdef SK_DEVELOPER |
| 1645 void SkBitmap::toString(SkString* str) const { | 1693 void SkBitmap::toString(SkString* str) const { |
| 1646 | 1694 |
| 1647 static const char* gConfigNames[kConfigCount] = { | 1695 static const char* gConfigNames[kConfigCount] = { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1673 if (NULL != uri) { | 1721 if (NULL != uri) { |
| 1674 str->appendf(" uri:\"%s\"", uri); | 1722 str->appendf(" uri:\"%s\"", uri); |
| 1675 } else { | 1723 } else { |
| 1676 str->appendf(" pixelref:%p", pr); | 1724 str->appendf(" pixelref:%p", pr); |
| 1677 } | 1725 } |
| 1678 } | 1726 } |
| 1679 | 1727 |
| 1680 str->append(")"); | 1728 str->append(")"); |
| 1681 } | 1729 } |
| 1682 #endif | 1730 #endif |
| 1683 | |
| 1684 /////////////////////////////////////////////////////////////////////////////// | |
| 1685 | |
| 1686 #ifdef SK_DEBUG | |
| 1687 void SkImageInfo::validate() const { | |
| 1688 SkASSERT(fWidth >= 0); | |
| 1689 SkASSERT(fHeight >= 0); | |
| 1690 SkASSERT(SkColorTypeIsValid(fColorType)); | |
| 1691 SkASSERT(SkAlphaTypeIsValid(fAlphaType)); | |
| 1692 } | |
| 1693 #endif | |
| OLD | NEW |