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