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 */
13static 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
21size_t SkMask::computeImageSize() const {
22    return safeMul32(fBounds.height(), fRowBytes);
23}
24
25size_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*/
36uint8_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*/
43void SkMask::FreeImage(void* image) {
44    sk_free(image);
45}
46
47///////////////////////////////////////////////////////////////////////////////
48
49static 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
58static 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
64void* 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}
74