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