Home | History | Annotate | Download | only in core
      1 
      2 /*
      3  * Copyright 2009 The Android Open Source Project
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 
     10 #include "SkColorTable.h"
     11 #include "SkReadBuffer.h"
     12 #include "SkWriteBuffer.h"
     13 #include "SkStream.h"
     14 #include "SkTemplates.h"
     15 
     16 // As copy constructor is hidden in the class hierarchy, we need to call
     17 // default constructor explicitly to suppress a compiler warning.
     18 SkColorTable::SkColorTable(const SkColorTable& src) : INHERITED() {
     19     f16BitCache = NULL;
     20     fAlphaType = src.fAlphaType;
     21     int count = src.count();
     22     fCount = SkToU16(count);
     23     fColors = reinterpret_cast<SkPMColor*>(
     24                                     sk_malloc_throw(count * sizeof(SkPMColor)));
     25     memcpy(fColors, src.fColors, count * sizeof(SkPMColor));
     26 
     27     SkDEBUGCODE(fColorLockCount = 0;)
     28     SkDEBUGCODE(f16BitCacheLockCount = 0;)
     29 }
     30 
     31 SkColorTable::SkColorTable(const SkPMColor colors[], int count, SkAlphaType at)
     32     : f16BitCache(NULL), fAlphaType(SkToU8(at))
     33 {
     34     SkASSERT(0 == count || NULL != colors);
     35 
     36     if (count < 0) {
     37         count = 0;
     38     } else if (count > 256) {
     39         count = 256;
     40     }
     41 
     42     fCount = SkToU16(count);
     43     fColors = reinterpret_cast<SkPMColor*>(
     44                                     sk_malloc_throw(count * sizeof(SkPMColor)));
     45 
     46     memcpy(fColors, colors, count * sizeof(SkPMColor));
     47 
     48     SkDEBUGCODE(fColorLockCount = 0;)
     49     SkDEBUGCODE(f16BitCacheLockCount = 0;)
     50 }
     51 
     52 SkColorTable::~SkColorTable()
     53 {
     54     SkASSERT(fColorLockCount == 0);
     55     SkASSERT(f16BitCacheLockCount == 0);
     56 
     57     sk_free(fColors);
     58     sk_free(f16BitCache);
     59 }
     60 
     61 void SkColorTable::unlockColors() {
     62     SkASSERT(fColorLockCount != 0);
     63     SkDEBUGCODE(sk_atomic_dec(&fColorLockCount);)
     64 }
     65 
     66 #include "SkColorPriv.h"
     67 
     68 static inline void build_16bitcache(uint16_t dst[], const SkPMColor src[],
     69                                     int count) {
     70     while (--count >= 0) {
     71         *dst++ = SkPixel32ToPixel16_ToU16(*src++);
     72     }
     73 }
     74 
     75 const uint16_t* SkColorTable::lock16BitCache() {
     76     // Assert that we're opaque, since our 16-bit cache will be sort of useless
     77     // if there is alpha (which we're throwing away)
     78     SkASSERT(this->isOpaque());
     79     if (NULL == f16BitCache) {
     80         f16BitCache = (uint16_t*)sk_malloc_throw(fCount * sizeof(uint16_t));
     81         build_16bitcache(f16BitCache, fColors, fCount);
     82     }
     83 
     84     SkDEBUGCODE(f16BitCacheLockCount += 1);
     85     return f16BitCache;
     86 }
     87 
     88 ///////////////////////////////////////////////////////////////////////////////
     89 
     90 SkColorTable::SkColorTable(SkReadBuffer& buffer) {
     91     f16BitCache = NULL;
     92     SkDEBUGCODE(fColorLockCount = 0;)
     93     SkDEBUGCODE(f16BitCacheLockCount = 0;)
     94 
     95     fAlphaType = SkToU8(buffer.readUInt());
     96     fCount = buffer.getArrayCount();
     97     size_t allocSize = fCount * sizeof(SkPMColor);
     98     SkDEBUGCODE(bool success = false;)
     99     if (buffer.validateAvailable(allocSize)) {
    100         fColors = (SkPMColor*)sk_malloc_throw(allocSize);
    101         SkDEBUGCODE(success =) buffer.readColorArray(fColors, fCount);
    102     } else {
    103         fCount = 0;
    104         fColors = NULL;
    105     }
    106 #ifdef SK_DEBUG
    107     SkASSERT((unsigned)fCount <= 256);
    108     SkASSERT(success);
    109 #endif
    110 }
    111 
    112 void SkColorTable::writeToBuffer(SkWriteBuffer& buffer) const {
    113     buffer.writeUInt(fAlphaType);
    114     buffer.writeColorArray(fColors, fCount);
    115 }
    116