epoger@google.com | ec3ed6a | 2011-07-28 14:26:00 +0000 | [diff] [blame] | 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 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 8 | #include "SkMask.h" |
| 9 | |
reed@android.com | 543ed93 | 2009-04-24 12:43:40 +0000 | [diff] [blame] | 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) { |
reed@google.com | bf0001d | 2014-01-13 14:53:55 +0000 | [diff] [blame] | 14 | int64_t size = sk_64_mul(a, b); |
| 15 | if (size > 0 && sk_64_isS32(size)) { |
| 16 | return sk_64_asS32(size); |
reed@android.com | 543ed93 | 2009-04-24 12:43:40 +0000 | [diff] [blame] | 17 | } |
| 18 | return 0; |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 19 | } |
| 20 | |
reed@android.com | 543ed93 | 2009-04-24 12:43:40 +0000 | [diff] [blame] | 21 | size_t SkMask::computeImageSize() const { |
| 22 | return safeMul32(fBounds.height(), fRowBytes); |
| 23 | } |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 24 | |
reed@android.com | 543ed93 | 2009-04-24 12:43:40 +0000 | [diff] [blame] | 25 | size_t SkMask::computeTotalImageSize() const { |
| 26 | size_t size = this->computeImageSize(); |
| 27 | if (fFormat == SkMask::k3D_Format) { |
commit-bot@chromium.org | a8c7f77 | 2014-01-24 21:46:29 +0000 | [diff] [blame] | 28 | size = safeMul32(SkToS32(size), 3); |
reed@android.com | 543ed93 | 2009-04-24 12:43:40 +0000 | [diff] [blame] | 29 | } |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 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 | */ |
mike@reedtribe.org | d11f0e0 | 2011-04-09 19:39:25 +0000 | [diff] [blame] | 36 | uint8_t* SkMask::AllocImage(size_t size) { |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 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 | */ |
mike@reedtribe.org | d11f0e0 | 2011-04-09 19:39:25 +0000 | [diff] [blame] | 43 | void SkMask::FreeImage(void* image) { |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 44 | sk_free(image); |
| 45 | } |
| 46 | |
reed@google.com | f52e555 | 2011-10-18 17:29:44 +0000 | [diff] [blame] | 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); |
rmistry@google.com | fbfcd56 | 2012-08-23 18:09:54 +0000 | [diff] [blame] | 68 | |
reed@google.com | f52e555 | 2011-10-18 17:29:44 +0000 | [diff] [blame] | 69 | char* addr = (char*)fImage; |
| 70 | addr += (y - fBounds.fTop) * fRowBytes; |
| 71 | addr += (x - fBounds.fLeft) << maskFormatToShift(fFormat); |
| 72 | return addr; |
| 73 | } |