Home | History | Annotate | Download | only in core
      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  */
     15 static 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 
     24 size_t SkMask::computeImageSize() const {
     25     return safeMul32(fBounds.height(), fRowBytes);
     26 }
     27 
     28 size_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 */
     39 uint8_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 */
     46 void SkMask::FreeImage(void* image) {
     47     sk_free(image);
     48 }
     49 
     50 ///////////////////////////////////////////////////////////////////////////////
     51 
     52 static 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 
     61 static 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 
     67 void* 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