blob: 929835717ba95fe2c6c6cf4c7382e02d02911158 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001/*
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
reed@android.com8a1c16f2008-12-17 15:59:43 +00008#include "SkMask.h"
9
reed@android.com543ed932009-04-24 12:43:40 +000010/** 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) {
reed@google.combf0001d2014-01-13 14:53:55 +000014 int64_t size = sk_64_mul(a, b);
15 if (size > 0 && sk_64_isS32(size)) {
16 return sk_64_asS32(size);
reed@android.com543ed932009-04-24 12:43:40 +000017 }
18 return 0;
reed@android.com8a1c16f2008-12-17 15:59:43 +000019}
20
reed@android.com543ed932009-04-24 12:43:40 +000021size_t SkMask::computeImageSize() const {
22 return safeMul32(fBounds.height(), fRowBytes);
23}
reed@android.com8a1c16f2008-12-17 15:59:43 +000024
reed@android.com543ed932009-04-24 12:43:40 +000025size_t SkMask::computeTotalImageSize() const {
26 size_t size = this->computeImageSize();
27 if (fFormat == SkMask::k3D_Format) {
commit-bot@chromium.orga8c7f772014-01-24 21:46:29 +000028 size = safeMul32(SkToS32(size), 3);
reed@android.com543ed932009-04-24 12:43:40 +000029 }
reed@android.com8a1c16f2008-12-17 15:59:43 +000030 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*/
mike@reedtribe.orgd11f0e02011-04-09 19:39:25 +000036uint8_t* SkMask::AllocImage(size_t size) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000037 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*/
mike@reedtribe.orgd11f0e02011-04-09 19:39:25 +000043void SkMask::FreeImage(void* image) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000044 sk_free(image);
45}
46
reed@google.comf52e5552011-10-18 17:29:44 +000047///////////////////////////////////////////////////////////////////////////////
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);
rmistry@google.comfbfcd562012-08-23 18:09:54 +000068
reed@google.comf52e5552011-10-18 17:29:44 +000069 char* addr = (char*)fImage;
70 addr += (y - fBounds.fTop) * fRowBytes;
71 addr += (x - fBounds.fLeft) << maskFormatToShift(fFormat);
72 return addr;
73}