Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1103)

Side by Side Diff: src/core/SkBitmap.cpp

Issue 137753017: move all Config specific APIs into SkBitmapConfig.cpp -- Config is deprecated (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « include/core/SkWriteBuffer.h ('k') | src/core/SkBitmapConfig.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 SkTSwap(fFlags, other.fFlags); 135 SkTSwap(fFlags, other.fFlags);
136 136
137 SkDEBUGCODE(this->validate();) 137 SkDEBUGCODE(this->validate();)
138 } 138 }
139 139
140 void SkBitmap::reset() { 140 void SkBitmap::reset() {
141 this->freePixels(); 141 this->freePixels();
142 sk_bzero(this, sizeof(*this)); 142 sk_bzero(this, sizeof(*this));
143 } 143 }
144 144
145 SkBitmap::Config SkBitmap::config() const {
146 return SkColorTypeToBitmapConfig(fInfo.colorType());
147 }
148
149 int SkBitmap::ComputeBytesPerPixel(SkBitmap::Config config) {
150 int bpp;
151 switch (config) {
152 case kNo_Config:
153 bpp = 0; // not applicable
154 break;
155 case kA8_Config:
156 case kIndex8_Config:
157 bpp = 1;
158 break;
159 case kRGB_565_Config:
160 case kARGB_4444_Config:
161 bpp = 2;
162 break;
163 case kARGB_8888_Config:
164 bpp = 4;
165 break;
166 default:
167 SkDEBUGFAIL("unknown config");
168 bpp = 0; // error
169 break;
170 }
171 return bpp;
172 }
173
174 size_t SkBitmap::ComputeRowBytes(Config c, int width) {
175 return SkColorTypeMinRowBytes(SkBitmapConfigToColorType(c), width);
176 }
177
178 int64_t SkBitmap::ComputeSize64(Config config, int width, int height) {
179 SkColorType ct = SkBitmapConfigToColorType(config);
180 int64_t rowBytes = sk_64_mul(SkColorTypeBytesPerPixel(ct), width);
181 return rowBytes * height;
182 }
183
184 size_t SkBitmap::ComputeSize(Config c, int width, int height) {
185 int64_t size = SkBitmap::ComputeSize64(c, width, height);
186 return sk_64_isS32(size) ? sk_64_asS32(size) : 0;
187 }
188
189 int64_t SkBitmap::ComputeSafeSize64(Config config,
190 uint32_t width,
191 uint32_t height,
192 size_t rowBytes) {
193 SkImageInfo info = SkImageInfo::Make(width, height,
194 SkBitmapConfigToColorType(config),
195 kPremul_SkAlphaType);
196 return info.getSafeSize64(rowBytes);
197 }
198
199 size_t SkBitmap::ComputeSafeSize(Config config,
200 uint32_t width,
201 uint32_t height,
202 size_t rowBytes) {
203 int64_t safeSize = ComputeSafeSize64(config, width, height, rowBytes);
204 int32_t safeSize32 = (int32_t)safeSize;
205
206 if (safeSize32 != safeSize) {
207 safeSize32 = 0;
208 }
209 return safeSize32;
210 }
211
212 void SkBitmap::getBounds(SkRect* bounds) const { 145 void SkBitmap::getBounds(SkRect* bounds) const {
213 SkASSERT(bounds); 146 SkASSERT(bounds);
214 bounds->set(0, 0, 147 bounds->set(0, 0,
215 SkIntToScalar(fInfo.fWidth), SkIntToScalar(fInfo.fHeight)); 148 SkIntToScalar(fInfo.fWidth), SkIntToScalar(fInfo.fHeight));
216 } 149 }
217 150
218 void SkBitmap::getBounds(SkIRect* bounds) const { 151 void SkBitmap::getBounds(SkIRect* bounds) const {
219 SkASSERT(bounds); 152 SkASSERT(bounds);
220 bounds->set(0, 0, fInfo.fWidth, fInfo.fHeight); 153 bounds->set(0, 0, fInfo.fWidth, fInfo.fHeight);
221 } 154 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 return reset_return_false(this); 208 return reset_return_false(this);
276 } 209 }
277 210
278 this->freePixels(); 211 this->freePixels();
279 212
280 fInfo = info; 213 fInfo = info;
281 fRowBytes = SkToU32(rowBytes); 214 fRowBytes = SkToU32(rowBytes);
282 return true; 215 return true;
283 } 216 }
284 217
285 bool SkBitmap::setConfig(Config config, int width, int height, size_t rowBytes,
286 SkAlphaType alphaType) {
287 SkColorType ct = SkBitmapConfigToColorType(config);
288 return this->setConfig(SkImageInfo::Make(width, height, ct, alphaType),
289 rowBytes);
290 }
291
292 bool SkBitmap::setAlphaType(SkAlphaType alphaType) { 218 bool SkBitmap::setAlphaType(SkAlphaType alphaType) {
293 if (!validate_alphaType(fInfo.fColorType, alphaType, &alphaType)) { 219 if (!validate_alphaType(fInfo.fColorType, alphaType, &alphaType)) {
294 return false; 220 return false;
295 } 221 }
296 if (fInfo.fAlphaType != alphaType) { 222 if (fInfo.fAlphaType != alphaType) {
297 fInfo.fAlphaType = alphaType; 223 fInfo.fAlphaType = alphaType;
298 if (fPixelRef) { 224 if (fPixelRef) {
299 fPixelRef->changeAlphaType(alphaType); 225 fPixelRef->changeAlphaType(alphaType);
300 } 226 }
301 } 227 }
(...skipping 14 matching lines...) Expand all
316 fPixels = p; 242 fPixels = p;
317 fColorTable = fPixelRef->colorTable(); 243 fColorTable = fPixelRef->colorTable();
318 } else { 244 } else {
319 SkASSERT(0 == fPixelLockCount); 245 SkASSERT(0 == fPixelLockCount);
320 fPixels = NULL; 246 fPixels = NULL;
321 fColorTable = NULL; 247 fColorTable = NULL;
322 } 248 }
323 } 249 }
324 } 250 }
325 251
326 static bool config_to_colorType(SkBitmap::Config config, SkColorType* ctOut) {
327 SkColorType ct;
328 switch (config) {
329 case SkBitmap::kA8_Config:
330 ct = kAlpha_8_SkColorType;
331 break;
332 case SkBitmap::kIndex8_Config:
333 ct = kIndex_8_SkColorType;
334 break;
335 case SkBitmap::kRGB_565_Config:
336 ct = kRGB_565_SkColorType;
337 break;
338 case SkBitmap::kARGB_4444_Config:
339 ct = kARGB_4444_SkColorType;
340 break;
341 case SkBitmap::kARGB_8888_Config:
342 ct = kPMColor_SkColorType;
343 break;
344 case SkBitmap::kNo_Config:
345 default:
346 return false;
347 }
348 if (ctOut) {
349 *ctOut = ct;
350 }
351 return true;
352 }
353
354 SkPixelRef* SkBitmap::setPixelRef(SkPixelRef* pr, int dx, int dy) { 252 SkPixelRef* SkBitmap::setPixelRef(SkPixelRef* pr, int dx, int dy) {
355 #ifdef SK_DEBUG 253 #ifdef SK_DEBUG
356 if (pr) { 254 if (pr) {
357 SkImageInfo info; 255 SkImageInfo info;
358 if (this->asImageInfo(&info)) { 256 if (this->asImageInfo(&info)) {
359 const SkImageInfo& prInfo = pr->info(); 257 const SkImageInfo& prInfo = pr->info();
360 SkASSERT(info.fWidth <= prInfo.fWidth); 258 SkASSERT(info.fWidth <= prInfo.fWidth);
361 SkASSERT(info.fHeight <= prInfo.fHeight); 259 SkASSERT(info.fHeight <= prInfo.fHeight);
362 SkASSERT(info.fColorType == prInfo.fColorType); 260 SkASSERT(info.fColorType == prInfo.fColorType);
363 switch (prInfo.fAlphaType) { 261 switch (prInfo.fAlphaType) {
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
500 releaseProc, context); 398 releaseProc, context);
501 if (!pr) { 399 if (!pr) {
502 this->reset(); 400 this->reset();
503 return false; 401 return false;
504 } 402 }
505 403
506 this->setPixelRef(pr)->unref(); 404 this->setPixelRef(pr)->unref();
507 return true; 405 return true;
508 } 406 }
509 407
510 bool SkBitmap::allocConfigPixels(Config config, int width, int height,
511 bool isOpaque) {
512 SkColorType ct;
513 if (!config_to_colorType(config, &ct)) {
514 return false;
515 }
516
517 SkAlphaType at = isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType;
518 return this->allocPixels(SkImageInfo::Make(width, height, ct, at));
519 }
520
521 /////////////////////////////////////////////////////////////////////////////// 408 ///////////////////////////////////////////////////////////////////////////////
522 409
523 void SkBitmap::freePixels() { 410 void SkBitmap::freePixels() {
524 // if we're gonna free the pixels, we certainly need to free the mipmap 411 // if we're gonna free the pixels, we certainly need to free the mipmap
525 this->freeMipMap(); 412 this->freeMipMap();
526 413
527 if (NULL != fPixelRef) { 414 if (NULL != fPixelRef) {
528 if (fPixelLockCount > 0) { 415 if (fPixelLockCount > 0) {
529 fPixelRef->unlockPixels(); 416 fPixelRef->unlockPixels();
530 } 417 }
(...skipping 28 matching lines...) Expand all
559 return fPixelRef ? fPixelRef->getTexture() : NULL; 446 return fPixelRef ? fPixelRef->getTexture() : NULL;
560 } 447 }
561 448
562 /////////////////////////////////////////////////////////////////////////////// 449 ///////////////////////////////////////////////////////////////////////////////
563 450
564 /** We explicitly use the same allocator for our pixels that SkMask does, 451 /** We explicitly use the same allocator for our pixels that SkMask does,
565 so that we can freely assign memory allocated by one class to the other. 452 so that we can freely assign memory allocated by one class to the other.
566 */ 453 */
567 bool SkBitmap::HeapAllocator::allocPixelRef(SkBitmap* dst, 454 bool SkBitmap::HeapAllocator::allocPixelRef(SkBitmap* dst,
568 SkColorTable* ctable) { 455 SkColorTable* ctable) {
569 SkImageInfo info; 456 SkPixelRef* pr = SkMallocPixelRef::NewAllocate(dst->info(), dst->rowBytes(),
570 if (!dst->asImageInfo(&info)) {
571 // SkDebugf("unsupported config for info %d\n", dst->config());
572 return false;
573 }
574
575 SkPixelRef* pr = SkMallocPixelRef::NewAllocate(info, dst->rowBytes(),
576 ctable); 457 ctable);
577 if (NULL == pr) { 458 if (NULL == pr) {
578 return false; 459 return false;
579 } 460 }
580 461
581 dst->setPixelRef(pr)->unref(); 462 dst->setPixelRef(pr)->unref();
582 // since we're already allocated, we lockPixels right away 463 // since we're already allocated, we lockPixels right away
583 dst->lockPixels(); 464 dst->lockPixels();
584 return true; 465 return true;
585 } 466 }
(...skipping 13 matching lines...) Expand all
599 } 480 }
600 481
601 if (!preserveDstPad && static_cast<uint32_t>(dstRowBytes) == fRowBytes) { 482 if (!preserveDstPad && static_cast<uint32_t>(dstRowBytes) == fRowBytes) {
602 size_t safeSize = this->getSafeSize(); 483 size_t safeSize = this->getSafeSize();
603 if (safeSize > dstSize || safeSize == 0) 484 if (safeSize > dstSize || safeSize == 0)
604 return false; 485 return false;
605 else { 486 else {
606 SkAutoLockPixels lock(*this); 487 SkAutoLockPixels lock(*this);
607 // This implementation will write bytes beyond the end of each row, 488 // This implementation will write bytes beyond the end of each row,
608 // excluding the last row, if the bitmap's stride is greater than 489 // excluding the last row, if the bitmap's stride is greater than
609 // strictly required by the current config. 490 // strictly required by the current colorType.
610 memcpy(dst, getPixels(), safeSize); 491 memcpy(dst, getPixels(), safeSize);
611 492
612 return true; 493 return true;
613 } 494 }
614 } else { 495 } else {
615 // If destination has different stride than us, then copy line by line. 496 // If destination has different stride than us, then copy line by line.
616 if (fInfo.getSafeSize(dstRowBytes) > dstSize) { 497 if (fInfo.getSafeSize(dstRowBytes) > dstSize) {
617 return false; 498 return false;
618 } else { 499 } else {
619 // Just copy what we need on each line. 500 // Just copy what we need on each line.
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
672 break; 553 break;
673 case kARGB_4444_SkColorType: 554 case kARGB_4444_SkColorType:
674 case kRGB_565_SkColorType: 555 case kRGB_565_SkColorType:
675 base += x << 1; 556 base += x << 1;
676 break; 557 break;
677 case kAlpha_8_SkColorType: 558 case kAlpha_8_SkColorType:
678 case kIndex_8_SkColorType: 559 case kIndex_8_SkColorType:
679 base += x; 560 base += x;
680 break; 561 break;
681 default: 562 default:
682 SkDEBUGFAIL("Can't return addr for config"); 563 SkDEBUGFAIL("Can't return addr for colorType");
683 base = NULL; 564 base = NULL;
684 break; 565 break;
685 } 566 }
686 } 567 }
687 return base; 568 return base;
688 } 569 }
689 570
690 SkColor SkBitmap::getColor(int x, int y) const { 571 SkColor SkBitmap::getColor(int x, int y) const {
691 SkASSERT((unsigned)x < (unsigned)this->width()); 572 SkASSERT((unsigned)x < (unsigned)this->width());
692 SkASSERT((unsigned)y < (unsigned)this->height()); 573 SkASSERT((unsigned)y < (unsigned)this->height());
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
949 // share the pixelref with a custom offset 830 // share the pixelref with a custom offset
950 dst.setPixelRef(fPixelRef, origin); 831 dst.setPixelRef(fPixelRef, origin);
951 } 832 }
952 SkDEBUGCODE(dst.validate();) 833 SkDEBUGCODE(dst.validate();)
953 834
954 // we know we're good, so commit to result 835 // we know we're good, so commit to result
955 result->swap(dst); 836 result->swap(dst);
956 return true; 837 return true;
957 } 838 }
958 839
840 bool SkBitmap::canCopyTo(SkColorType dstColorType) const {
841 if (kUnknown_SkColorType == this->colorType()) {
842 return false;
843 }
844
845 bool sameColorTypes = (this->colorType() == dstColorType);
846 switch (dstColorType) {
847 case kAlpha_8_SkColorType:
848 case kRGB_565_SkColorType:
849 case kPMColor_SkColorType:
850 break;
851 case kIndex_8_SkColorType:
852 if (!sameColorTypes) {
853 return false;
854 }
855 break;
856 case kARGB_4444_SkColorType:
857 return sameColorTypes || kPMColor_SkColorType == this->colorType();
858 default:
859 return false;
860 }
861 return true;
862 }
863
959 /////////////////////////////////////////////////////////////////////////////// 864 ///////////////////////////////////////////////////////////////////////////////
960 865
961 #include "SkCanvas.h" 866 #include "SkCanvas.h"
962 #include "SkPaint.h" 867 #include "SkPaint.h"
963 868
964 bool SkBitmap::canCopyTo(Config dstConfig) const {
965 if (this->config() == kNo_Config) {
966 return false;
967 }
968
969 bool sameConfigs = (this->config() == dstConfig);
970 switch (dstConfig) {
971 case kA8_Config:
972 case kRGB_565_Config:
973 case kARGB_8888_Config:
974 break;
975 case kIndex8_Config:
976 if (!sameConfigs) {
977 return false;
978 }
979 break;
980 case kARGB_4444_Config:
981 return sameConfigs || kARGB_8888_Config == this->config();
982 default:
983 return false;
984 }
985 return true;
986 }
987
988 bool SkBitmap::copyTo(SkBitmap* dst, Config dstConfig, Allocator* alloc) const {
989 if (!this->canCopyTo(dstConfig)) {
990 return false;
991 }
992
993 // if we have a texture, first get those pixels
994 SkBitmap tmpSrc;
995 const SkBitmap* src = this;
996
997 if (fPixelRef) {
998 SkIRect subset;
999 subset.setXYWH(fPixelRefOrigin.fX, fPixelRefOrigin.fY,
1000 fInfo.width(), fInfo.height());
1001 if (fPixelRef->readPixels(&tmpSrc, &subset)) {
1002 SkASSERT(tmpSrc.width() == this->width());
1003 SkASSERT(tmpSrc.height() == this->height());
1004
1005 // did we get lucky and we can just return tmpSrc?
1006 if (tmpSrc.config() == dstConfig && NULL == alloc) {
1007 dst->swap(tmpSrc);
1008 // If the result is an exact copy, clone the gen ID.
1009 if (dst->pixelRef() && dst->pixelRef()->info() == fPixelRef->inf o()) {
1010 dst->pixelRef()->cloneGenID(*fPixelRef);
1011 }
1012 return true;
1013 }
1014
1015 // fall through to the raster case
1016 src = &tmpSrc;
1017 }
1018 }
1019
1020 // we lock this now, since we may need its colortable
1021 SkAutoLockPixels srclock(*src);
1022 if (!src->readyToDraw()) {
1023 return false;
1024 }
1025
1026 // The only way to be readyToDraw is if fPixelRef is non NULL.
1027 SkASSERT(fPixelRef != NULL);
1028
1029 SkBitmap tmpDst;
1030 tmpDst.setConfig(dstConfig, src->width(), src->height(), 0,
1031 src->alphaType());
1032
1033 // allocate colortable if srcConfig == kIndex8_Config
1034 SkColorTable* ctable = (dstConfig == kIndex8_Config) ?
1035 new SkColorTable(*src->getColorTable()) : NULL;
1036 SkAutoUnref au(ctable);
1037 if (!tmpDst.allocPixels(alloc, ctable)) {
1038 return false;
1039 }
1040
1041 if (!tmpDst.readyToDraw()) {
1042 // allocator/lock failed
1043 return false;
1044 }
1045
1046 // pixelRef must be non NULL or tmpDst.readyToDraw() would have
1047 // returned false.
1048 SkASSERT(tmpDst.pixelRef() != NULL);
1049
1050 /* do memcpy for the same configs cases, else use drawing
1051 */
1052 if (src->config() == dstConfig) {
1053 if (tmpDst.getSize() == src->getSize()) {
1054 memcpy(tmpDst.getPixels(), src->getPixels(), src->getSafeSize());
1055 SkPixelRef* pixelRef = tmpDst.pixelRef();
1056
1057 // In order to reach this point, we know that the width, config and
1058 // rowbytes of the SkPixelRefs are the same, but it is possible for
1059 // the heights to differ, if this SkBitmap's height is a subset of
1060 // fPixelRef. Only if the SkPixelRefs' heights match are we
1061 // guaranteed that this is an exact copy, meaning we should clone
1062 // the genID.
1063 if (pixelRef->info().fHeight == fPixelRef->info().fHeight) {
1064 // TODO: what to do if the two infos match, BUT
1065 // fPixelRef is premul and pixelRef is opaque?
1066 // skipping assert for now
1067 // https://code.google.com/p/skia/issues/detail?id=2012
1068 // SkASSERT(pixelRef->info() == fPixelRef->info());
1069 SkASSERT(pixelRef->info().fWidth == fPixelRef->info().fWidth);
1070 SkASSERT(pixelRef->info().fColorType == fPixelRef->info().fColor Type);
1071 pixelRef->cloneGenID(*fPixelRef);
1072 }
1073 } else {
1074 const char* srcP = reinterpret_cast<const char*>(src->getPixels());
1075 char* dstP = reinterpret_cast<char*>(tmpDst.getPixels());
1076 // to be sure we don't read too much, only copy our logical pixels
1077 size_t bytesToCopy = tmpDst.width() * tmpDst.bytesPerPixel();
1078 for (int y = 0; y < tmpDst.height(); y++) {
1079 memcpy(dstP, srcP, bytesToCopy);
1080 srcP += src->rowBytes();
1081 dstP += tmpDst.rowBytes();
1082 }
1083 }
1084 } else if (SkBitmap::kARGB_4444_Config == dstConfig
1085 && SkBitmap::kARGB_8888_Config == src->config()) {
1086 SkASSERT(src->height() == tmpDst.height());
1087 SkASSERT(src->width() == tmpDst.width());
1088 for (int y = 0; y < src->height(); ++y) {
1089 SkPMColor16* SK_RESTRICT dstRow = (SkPMColor16*) tmpDst.getAddr16(0, y);
1090 SkPMColor* SK_RESTRICT srcRow = (SkPMColor*) src->getAddr32(0, y);
1091 DITHER_4444_SCAN(y);
1092 for (int x = 0; x < src->width(); ++x) {
1093 dstRow[x] = SkDitherARGB32To4444(srcRow[x],
1094 DITHER_VALUE(x));
1095 }
1096 }
1097 } else {
1098 // Always clear the dest in case one of the blitters accesses it
1099 // TODO: switch the allocation of tmpDst to call sk_calloc_throw
1100 tmpDst.eraseColor(SK_ColorTRANSPARENT);
1101
1102 SkCanvas canvas(tmpDst);
1103 SkPaint paint;
1104
1105 paint.setDither(true);
1106 canvas.drawBitmap(*src, 0, 0, &paint);
1107 }
1108
1109 dst->swap(tmpDst);
1110 return true;
1111 }
1112
1113 bool SkBitmap::deepCopyTo(SkBitmap* dst, Config dstConfig) const {
1114 const SkColorType dstCT = SkBitmapConfigToColorType(dstConfig);
1115
1116 if (!this->canCopyTo(dstConfig)) {
1117 return false;
1118 }
1119
1120 // If we have a PixelRef, and it supports deep copy, use it.
1121 // Currently supported only by texture-backed bitmaps.
1122 if (fPixelRef) {
1123 SkPixelRef* pixelRef = fPixelRef->deepCopy(dstConfig);
1124 if (pixelRef) {
1125 uint32_t rowBytes;
1126 if (this->colorType() == dstCT) {
1127 // Since there is no subset to pass to deepCopy, and deepCopy
1128 // succeeded, the new pixel ref must be identical.
1129 SkASSERT(fPixelRef->info() == pixelRef->info());
1130 pixelRef->cloneGenID(*fPixelRef);
1131 // Use the same rowBytes as the original.
1132 rowBytes = fRowBytes;
1133 } else {
1134 // With the new config, an appropriate fRowBytes will be compute d by setConfig.
1135 rowBytes = 0;
1136 }
1137
1138 SkImageInfo info = fInfo;
1139 info.fColorType = dstCT;
1140 if (!dst->setConfig(info, rowBytes)) {
1141 return false;
1142 }
1143 dst->setPixelRef(pixelRef, fPixelRefOrigin)->unref();
1144 return true;
1145 }
1146 }
1147
1148 if (this->getTexture()) {
1149 return false;
1150 } else {
1151 return this->copyTo(dst, dstConfig, NULL);
1152 }
1153 }
1154
1155 /////////////////////////////////////////////////////////////////////////////// 869 ///////////////////////////////////////////////////////////////////////////////
1156 /////////////////////////////////////////////////////////////////////////////// 870 ///////////////////////////////////////////////////////////////////////////////
1157 871
1158 static void downsampleby2_proc32(SkBitmap* dst, int x, int y, 872 static void downsampleby2_proc32(SkBitmap* dst, int x, int y,
1159 const SkBitmap& src) { 873 const SkBitmap& src) {
1160 x <<= 1; 874 x <<= 1;
1161 y <<= 1; 875 y <<= 1;
1162 const SkPMColor* p = src.getAddr32(x, y); 876 const SkPMColor* p = src.getAddr32(x, y);
1163 const SkPMColor* baseP = p; 877 const SkPMColor* baseP = p;
1164 SkPMColor c, ag, rb; 878 SkPMColor c, ag, rb;
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
1258 void SkBitmap::buildMipMap(bool forceRebuild) { 972 void SkBitmap::buildMipMap(bool forceRebuild) {
1259 if (forceRebuild) 973 if (forceRebuild)
1260 this->freeMipMap(); 974 this->freeMipMap();
1261 else if (fMipMap) 975 else if (fMipMap)
1262 return; // we're already built 976 return; // we're already built
1263 977
1264 SkASSERT(NULL == fMipMap); 978 SkASSERT(NULL == fMipMap);
1265 979
1266 void (*proc)(SkBitmap* dst, int x, int y, const SkBitmap& src); 980 void (*proc)(SkBitmap* dst, int x, int y, const SkBitmap& src);
1267 981
1268 const SkBitmap::Config config = this->config(); 982 const SkColorType ct = this->colorType();
1269 983
1270 switch (config) { 984 switch (ct) {
1271 case kARGB_8888_Config: 985 case kRGBA_8888_SkColorType:
986 case kBGRA_8888_SkColorType:
1272 proc = downsampleby2_proc32; 987 proc = downsampleby2_proc32;
1273 break; 988 break;
1274 case kRGB_565_Config: 989 case kRGB_565_SkColorType:
1275 proc = downsampleby2_proc16; 990 proc = downsampleby2_proc16;
1276 break; 991 break;
1277 case kARGB_4444_Config: 992 case kARGB_4444_SkColorType:
1278 proc = downsampleby2_proc4444; 993 proc = downsampleby2_proc4444;
1279 break; 994 break;
1280 case kIndex8_Config:
1281 case kA8_Config:
1282 default: 995 default:
1283 return; // don't build mipmaps for these configs 996 return; // don't build mipmaps for these configs
1284 } 997 }
1285 998
1286 SkAutoLockPixels alp(*this); 999 SkAutoLockPixels alp(*this);
1287 if (!this->readyToDraw()) { 1000 if (!this->readyToDraw()) {
1288 return; 1001 return;
1289 } 1002 }
1290 1003
1291 // whip through our loop to compute the exact size needed 1004 // whip through our loop to compute the exact size needed
1292 size_t size = 0; 1005 size_t size = 0;
1293 int maxLevels = 0; 1006 int maxLevels = 0;
1294 { 1007 {
1295 int width = this->width(); 1008 int width = this->width();
1296 int height = this->height(); 1009 int height = this->height();
1297 for (;;) { 1010 for (;;) {
1298 width >>= 1; 1011 width >>= 1;
1299 height >>= 1; 1012 height >>= 1;
1300 if (0 == width || 0 == height) { 1013 if (0 == width || 0 == height) {
1301 break; 1014 break;
1302 } 1015 }
1303 size += ComputeRowBytes(config, width) * height; 1016 size += SkColorTypeMinRowBytes(ct, width) * height;
1304 maxLevels += 1; 1017 maxLevels += 1;
1305 } 1018 }
1306 } 1019 }
1307 1020
1308 // nothing to build 1021 // nothing to build
1309 if (0 == maxLevels) { 1022 if (0 == maxLevels) {
1310 return; 1023 return;
1311 } 1024 }
1312 1025
1313 SkBitmap srcBM(*this); 1026 SkBitmap srcBM(*this);
(...skipping 10 matching lines...) Expand all
1324 MipLevel* level = mm->levels(); 1037 MipLevel* level = mm->levels();
1325 uint8_t* addr = (uint8_t*)mm->pixels(); 1038 uint8_t* addr = (uint8_t*)mm->pixels();
1326 int width = this->width(); 1039 int width = this->width();
1327 int height = this->height(); 1040 int height = this->height();
1328 uint32_t rowBytes; 1041 uint32_t rowBytes;
1329 SkBitmap dstBM; 1042 SkBitmap dstBM;
1330 1043
1331 for (int i = 0; i < maxLevels; i++) { 1044 for (int i = 0; i < maxLevels; i++) {
1332 width >>= 1; 1045 width >>= 1;
1333 height >>= 1; 1046 height >>= 1;
1334 rowBytes = SkToU32(ComputeRowBytes(config, width)); 1047 rowBytes = SkToU32(SkColorTypeMinRowBytes(ct, width));
1335 1048
1336 level[i].fPixels = addr; 1049 level[i].fPixels = addr;
1337 level[i].fWidth = width; 1050 level[i].fWidth = width;
1338 level[i].fHeight = height; 1051 level[i].fHeight = height;
1339 level[i].fRowBytes = rowBytes; 1052 level[i].fRowBytes = rowBytes;
1340 1053
1341 dstBM.setConfig(config, width, height, rowBytes); 1054 SkImageInfo info = this->info();
1342 dstBM.setPixels(addr); 1055 info.fWidth = width;
1056 info.fHeight = height;
1057 dstBM.installPixels(info, addr, rowBytes, NULL, NULL);
1343 1058
1344 srcBM.lockPixels(); 1059 srcBM.lockPixels();
1345 for (int y = 0; y < height; y++) { 1060 for (int y = 0; y < height; y++) {
1346 for (int x = 0; x < width; x++) { 1061 for (int x = 0; x < width; x++) {
1347 proc(&dstBM, x, y, srcBM); 1062 proc(&dstBM, x, y, srcBM);
1348 } 1063 }
1349 } 1064 }
1350 srcBM.unlockPixels(); 1065 srcBM.unlockPixels();
1351 1066
1352 srcBM = dstBM; 1067 srcBM = dstBM;
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after
1684 /////////////////////////////////////////////////////////////////////////////// 1399 ///////////////////////////////////////////////////////////////////////////////
1685 1400
1686 #ifdef SK_DEBUG 1401 #ifdef SK_DEBUG
1687 void SkImageInfo::validate() const { 1402 void SkImageInfo::validate() const {
1688 SkASSERT(fWidth >= 0); 1403 SkASSERT(fWidth >= 0);
1689 SkASSERT(fHeight >= 0); 1404 SkASSERT(fHeight >= 0);
1690 SkASSERT(SkColorTypeIsValid(fColorType)); 1405 SkASSERT(SkColorTypeIsValid(fColorType));
1691 SkASSERT(SkAlphaTypeIsValid(fAlphaType)); 1406 SkASSERT(SkAlphaTypeIsValid(fAlphaType));
1692 } 1407 }
1693 #endif 1408 #endif
OLDNEW
« no previous file with comments | « include/core/SkWriteBuffer.h ('k') | src/core/SkBitmapConfig.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698