Line data Source code
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 : #include "SkMalloc.h"
11 :
12 : //#define TRACK_SKMASK_LIFETIME
13 :
14 : /** returns the product if it is positive and fits in 31 bits. Otherwise this
15 : returns 0.
16 : */
17 0 : static int32_t safeMul32(int32_t a, int32_t b) {
18 0 : int64_t size = sk_64_mul(a, b);
19 0 : if (size > 0 && sk_64_isS32(size)) {
20 0 : return sk_64_asS32(size);
21 : }
22 0 : return 0;
23 : }
24 :
25 0 : size_t SkMask::computeImageSize() const {
26 0 : return safeMul32(fBounds.height(), fRowBytes);
27 : }
28 :
29 0 : size_t SkMask::computeTotalImageSize() const {
30 0 : size_t size = this->computeImageSize();
31 0 : if (fFormat == SkMask::k3D_Format) {
32 0 : size = safeMul32(SkToS32(size), 3);
33 : }
34 0 : return size;
35 : }
36 :
37 : #ifdef TRACK_SKMASK_LIFETIME
38 : static int gCounter;
39 : #endif
40 :
41 : /** We explicitly use this allocator for SkBimap pixels, so that we can
42 : freely assign memory allocated by one class to the other.
43 : */
44 0 : uint8_t* SkMask::AllocImage(size_t size) {
45 : #ifdef TRACK_SKMASK_LIFETIME
46 : SkDebugf("SkMask::AllocImage %d\n", gCounter++);
47 : #endif
48 0 : return (uint8_t*)sk_malloc_throw(SkAlign4(size));
49 : }
50 :
51 : /** We explicitly use this allocator for SkBimap pixels, so that we can
52 : freely assign memory allocated by one class to the other.
53 : */
54 4 : void SkMask::FreeImage(void* image) {
55 : #ifdef TRACK_SKMASK_LIFETIME
56 : if (image) {
57 : SkDebugf("SkMask::FreeImage %d\n", --gCounter);
58 : }
59 : #endif
60 4 : sk_free(image);
61 4 : }
62 :
63 : ///////////////////////////////////////////////////////////////////////////////
64 :
65 : static const int gMaskFormatToShift[] = {
66 : ~0, // BW -- not supported
67 : 0, // A8
68 : 0, // 3D
69 : 2, // ARGB32
70 : 1, // LCD16
71 : };
72 :
73 522 : static int maskFormatToShift(SkMask::Format format) {
74 522 : SkASSERT((unsigned)format < SK_ARRAY_COUNT(gMaskFormatToShift));
75 522 : SkASSERT(SkMask::kBW_Format != format);
76 522 : return gMaskFormatToShift[format];
77 : }
78 :
79 522 : void* SkMask::getAddr(int x, int y) const {
80 522 : SkASSERT(kBW_Format != fFormat);
81 522 : SkASSERT(fBounds.contains(x, y));
82 522 : SkASSERT(fImage);
83 :
84 522 : char* addr = (char*)fImage;
85 522 : addr += (y - fBounds.fTop) * fRowBytes;
86 522 : addr += (x - fBounds.fLeft) << maskFormatToShift(fFormat);
87 522 : return addr;
88 : }
|