|
1 /* |
|
2 * Copyright 2007 The Android Open Source Project |
|
3 * |
|
4 * Use of this source code is governed by a BSD-style license that can be |
|
5 * found in the LICENSE file. |
|
6 */ |
|
7 |
|
8 #include "SkMask.h" |
|
9 |
|
10 /** returns the product if it is positive and fits in 31 bits. Otherwise this |
|
11 returns 0. |
|
12 */ |
|
13 static int32_t safeMul32(int32_t a, int32_t b) { |
|
14 int64_t size = sk_64_mul(a, b); |
|
15 if (size > 0 && sk_64_isS32(size)) { |
|
16 return sk_64_asS32(size); |
|
17 } |
|
18 return 0; |
|
19 } |
|
20 |
|
21 size_t SkMask::computeImageSize() const { |
|
22 return safeMul32(fBounds.height(), fRowBytes); |
|
23 } |
|
24 |
|
25 size_t SkMask::computeTotalImageSize() const { |
|
26 size_t size = this->computeImageSize(); |
|
27 if (fFormat == SkMask::k3D_Format) { |
|
28 size = safeMul32(SkToS32(size), 3); |
|
29 } |
|
30 return size; |
|
31 } |
|
32 |
|
33 /** We explicitly use this allocator for SkBimap pixels, so that we can |
|
34 freely assign memory allocated by one class to the other. |
|
35 */ |
|
36 uint8_t* SkMask::AllocImage(size_t size) { |
|
37 return (uint8_t*)sk_malloc_throw(SkAlign4(size)); |
|
38 } |
|
39 |
|
40 /** We explicitly use this allocator for SkBimap pixels, so that we can |
|
41 freely assign memory allocated by one class to the other. |
|
42 */ |
|
43 void SkMask::FreeImage(void* image) { |
|
44 sk_free(image); |
|
45 } |
|
46 |
|
47 /////////////////////////////////////////////////////////////////////////////// |
|
48 |
|
49 static const int gMaskFormatToShift[] = { |
|
50 ~0, // BW -- not supported |
|
51 0, // A8 |
|
52 0, // 3D |
|
53 2, // ARGB32 |
|
54 1, // LCD16 |
|
55 2 // LCD32 |
|
56 }; |
|
57 |
|
58 static int maskFormatToShift(SkMask::Format format) { |
|
59 SkASSERT((unsigned)format < SK_ARRAY_COUNT(gMaskFormatToShift)); |
|
60 SkASSERT(SkMask::kBW_Format != format); |
|
61 return gMaskFormatToShift[format]; |
|
62 } |
|
63 |
|
64 void* SkMask::getAddr(int x, int y) const { |
|
65 SkASSERT(kBW_Format != fFormat); |
|
66 SkASSERT(fBounds.contains(x, y)); |
|
67 SkASSERT(fImage); |
|
68 |
|
69 char* addr = (char*)fImage; |
|
70 addr += (y - fBounds.fTop) * fRowBytes; |
|
71 addr += (x - fBounds.fLeft) << maskFormatToShift(fFormat); |
|
72 return addr; |
|
73 } |