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