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

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

Issue 122293002: Revert "Revert of https://codereview.chromium.org/113823003/" (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 6 years, 11 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/utils/SkRandom.h ('k') | src/core/SkMallocPixelRef.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"
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 "SkOrderedReadBuffer.h" 17 #include "SkOrderedReadBuffer.h"
18 #include "SkOrderedWriteBuffer.h" 18 #include "SkOrderedWriteBuffer.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 isPos32Bits(const Sk64& value) {
28 return !value.isNeg() && value.is32();
29 }
30
31 struct MipLevel { 27 struct MipLevel {
32 void* fPixels; 28 void* fPixels;
33 uint32_t fRowBytes; 29 uint32_t fRowBytes;
34 uint32_t fWidth, fHeight; 30 uint32_t fWidth, fHeight;
35 }; 31 };
36 32
37 struct SkBitmap::MipMap : SkNoncopyable { 33 struct SkBitmap::MipMap : SkNoncopyable {
38 int32_t fRefCnt; 34 int32_t fRefCnt;
39 int fLevelCount; 35 int fLevelCount;
40 // MipLevel fLevel[fLevelCount]; 36 // MipLevel fLevel[fLevelCount];
41 // Pixels[] 37 // Pixels[]
42 38
43 static MipMap* Alloc(int levelCount, size_t pixelSize) { 39 static MipMap* Alloc(int levelCount, size_t pixelSize) {
44 if (levelCount < 0) { 40 if (levelCount < 0) {
45 return NULL; 41 return NULL;
46 } 42 }
47 Sk64 size; 43 int64_t size = (levelCount + 1) * sizeof(MipLevel);
48 size.setMul(levelCount + 1, sizeof(MipLevel)); 44 size += sizeof(MipMap) + pixelSize;
49 size.add(sizeof(MipMap)); 45 if (!sk_64_isS32(size)) {
50 size.add(SkToS32(pixelSize));
51 if (!isPos32Bits(size)) {
52 return NULL; 46 return NULL;
53 } 47 }
54 MipMap* mm = (MipMap*)sk_malloc_throw(size.get32()); 48 MipMap* mm = (MipMap*)sk_malloc_throw(sk_64_asS32(size));
55 mm->fRefCnt = 1; 49 mm->fRefCnt = 1;
56 mm->fLevelCount = levelCount; 50 mm->fLevelCount = levelCount;
57 return mm; 51 return mm;
58 } 52 }
59 53
60 const MipLevel* levels() const { return (const MipLevel*)(this + 1); } 54 const MipLevel* levels() const { return (const MipLevel*)(this + 1); }
61 MipLevel* levels() { return (MipLevel*)(this + 1); } 55 MipLevel* levels() { return (MipLevel*)(this + 1); }
62 56
63 const void* pixels() const { return levels() + fLevelCount; } 57 const void* pixels() const { return levels() + fLevelCount; }
64 void* pixels() { return levels() + fLevelCount; } 58 void* pixels() { return levels() + fLevelCount; }
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 break; 172 break;
179 } 173 }
180 return bpp; 174 return bpp;
181 } 175 }
182 176
183 size_t SkBitmap::ComputeRowBytes(Config c, int width) { 177 size_t SkBitmap::ComputeRowBytes(Config c, int width) {
184 if (width < 0) { 178 if (width < 0) {
185 return 0; 179 return 0;
186 } 180 }
187 181
188 Sk64 rowBytes; 182 int64_t rowBytes = 0;
189 rowBytes.setZero();
190 183
191 switch (c) { 184 switch (c) {
192 case kNo_Config: 185 case kNo_Config:
193 break; 186 break;
194 case kA8_Config: 187 case kA8_Config:
195 case kIndex8_Config: 188 case kIndex8_Config:
196 rowBytes.set(width); 189 rowBytes = width;
197 break; 190 break;
198 case kRGB_565_Config: 191 case kRGB_565_Config:
199 case kARGB_4444_Config: 192 case kARGB_4444_Config:
200 rowBytes.set(width); 193 rowBytes = width << 1;
201 rowBytes.shiftLeft(1);
202 break; 194 break;
203 case kARGB_8888_Config: 195 case kARGB_8888_Config:
204 rowBytes.set(width); 196 rowBytes = width << 2;
205 rowBytes.shiftLeft(2);
206 break; 197 break;
207 default: 198 default:
208 SkDEBUGFAIL("unknown config"); 199 SkDEBUGFAIL("unknown config");
209 break; 200 break;
210 } 201 }
211 return isPos32Bits(rowBytes) ? rowBytes.get32() : 0; 202 return sk_64_isS32(rowBytes) ? sk_64_asS32(rowBytes) : 0;
212 } 203 }
213 204
214 Sk64 SkBitmap::ComputeSize64(Config c, int width, int height) { 205 int64_t SkBitmap::ComputeSize64(Config config, int width, int height) {
215 Sk64 size; 206 int64_t rowBytes = sk_64_mul(ComputeBytesPerPixel(config), width);
216 size.setMul(SkToS32(SkBitmap::ComputeRowBytes(c, width)), height); 207 return rowBytes * height;
217 return size;
218 } 208 }
219 209
220 size_t SkBitmap::ComputeSize(Config c, int width, int height) { 210 size_t SkBitmap::ComputeSize(Config c, int width, int height) {
221 Sk64 size = SkBitmap::ComputeSize64(c, width, height); 211 int64_t size = SkBitmap::ComputeSize64(c, width, height);
222 return isPos32Bits(size) ? size.get32() : 0; 212 return sk_64_isS32(size) ? sk_64_asS32(size) : 0;
223 } 213 }
224 214
225 Sk64 SkBitmap::ComputeSafeSize64(Config config, 215 int64_t SkBitmap::ComputeSafeSize64(Config config,
226 uint32_t width, 216 uint32_t width,
227 uint32_t height, 217 uint32_t height,
228 size_t rowBytes) { 218 size_t rowBytes) {
229 Sk64 safeSize; 219 int64_t safeSize = 0;
230 safeSize.setZero();
231 if (height > 0) { 220 if (height > 0) {
232 // TODO: Handle the case where the return value from 221 int64_t lastRow = sk_64_mul(ComputeBytesPerPixel(config), width);
233 // ComputeRowBytes is more than 31 bits. 222 safeSize = sk_64_mul(height - 1, rowBytes) + lastRow;
234 safeSize.set(SkToS32(ComputeRowBytes(config, width)));
235 Sk64 sizeAllButLastRow;
236 sizeAllButLastRow.setMul(height - 1, SkToS32(rowBytes));
237 safeSize.add(sizeAllButLastRow);
238 } 223 }
239 SkASSERT(!safeSize.isNeg()); 224 SkASSERT(safeSize >= 0);
240 return safeSize; 225 return safeSize;
241 } 226 }
242 227
243 size_t SkBitmap::ComputeSafeSize(Config config, 228 size_t SkBitmap::ComputeSafeSize(Config config,
244 uint32_t width, 229 uint32_t width,
245 uint32_t height, 230 uint32_t height,
246 size_t rowBytes) { 231 size_t rowBytes) {
247 Sk64 safeSize = ComputeSafeSize64(config, width, height, rowBytes); 232 int64_t safeSize = ComputeSafeSize64(config, width, height, rowBytes);
248 return (safeSize.is32() ? safeSize.get32() : 0); 233 int32_t safeSize32 = (int32_t)safeSize;
234
235 if (safeSize32 != safeSize) {
236 safeSize32 = 0;
237 }
238 return safeSize32;
249 } 239 }
250 240
251 void SkBitmap::getBounds(SkRect* bounds) const { 241 void SkBitmap::getBounds(SkRect* bounds) const {
252 SkASSERT(bounds); 242 SkASSERT(bounds);
253 bounds->set(0, 0, 243 bounds->set(0, 0,
254 SkIntToScalar(fWidth), SkIntToScalar(fHeight)); 244 SkIntToScalar(fWidth), SkIntToScalar(fHeight));
255 } 245 }
256 246
257 void SkBitmap::getBounds(SkIRect* bounds) const { 247 void SkBitmap::getBounds(SkIRect* bounds) const {
258 SkASSERT(bounds); 248 SkASSERT(bounds);
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
551 541
552 /////////////////////////////////////////////////////////////////////////////// 542 ///////////////////////////////////////////////////////////////////////////////
553 543
554 size_t SkBitmap::getSafeSize() const { 544 size_t SkBitmap::getSafeSize() const {
555 // This is intended to be a size_t version of ComputeSafeSize64(), just 545 // This is intended to be a size_t version of ComputeSafeSize64(), just
556 // faster. The computation is meant to be identical. 546 // faster. The computation is meant to be identical.
557 return (fHeight ? ((fHeight - 1) * fRowBytes) + 547 return (fHeight ? ((fHeight - 1) * fRowBytes) +
558 ComputeRowBytes(this->config(), fWidth): 0); 548 ComputeRowBytes(this->config(), fWidth): 0);
559 } 549 }
560 550
561 Sk64 SkBitmap::getSafeSize64() const {
562 return ComputeSafeSize64(this->config(), fWidth, fHeight, fRowBytes);
563 }
564
565 bool SkBitmap::copyPixelsTo(void* const dst, size_t dstSize, 551 bool SkBitmap::copyPixelsTo(void* const dst, size_t dstSize,
566 size_t dstRowBytes, bool preserveDstPad) const { 552 size_t dstRowBytes, bool preserveDstPad) const {
567 553
568 if (0 == dstRowBytes) { 554 if (0 == dstRowBytes) {
569 dstRowBytes = fRowBytes; 555 dstRowBytes = fRowBytes;
570 } 556 }
571 557
572 if (dstRowBytes < ComputeRowBytes(this->config(), fWidth) || 558 if (dstRowBytes < ComputeRowBytes(this->config(), fWidth) ||
573 dst == NULL || (getPixels() == NULL && pixelRef() == NULL)) 559 dst == NULL || (getPixels() == NULL && pixelRef() == NULL))
574 return false; 560 return false;
(...skipping 1136 matching lines...) Expand 10 before | Expand all | Expand 10 after
1711 if (NULL != uri) { 1697 if (NULL != uri) {
1712 str->appendf(" uri:\"%s\"", uri); 1698 str->appendf(" uri:\"%s\"", uri);
1713 } else { 1699 } else {
1714 str->appendf(" pixelref:%p", pr); 1700 str->appendf(" pixelref:%p", pr);
1715 } 1701 }
1716 } 1702 }
1717 1703
1718 str->append(")"); 1704 str->append(")");
1719 } 1705 }
1720 #endif 1706 #endif
OLDNEW
« no previous file with comments | « include/utils/SkRandom.h ('k') | src/core/SkMallocPixelRef.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698