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 || 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 if (this->isOpaque() && NULL == f16BitCache) { 77 f16BitCache = (uint16_t*)sk_malloc_throw(fCount * sizeof(uint16_t)); 78 build_16bitcache(f16BitCache, fColors, fCount); 79 } 80 81 SkDEBUGCODE(f16BitCacheLockCount += 1); 82 return f16BitCache; 83 } 84 85 /////////////////////////////////////////////////////////////////////////////// 86 87 SkColorTable::SkColorTable(SkReadBuffer& buffer) { 88 f16BitCache = NULL; 89 SkDEBUGCODE(fColorLockCount = 0;) 90 SkDEBUGCODE(f16BitCacheLockCount = 0;) 91 92 fAlphaType = SkToU8(buffer.readUInt()); 93 fCount = buffer.getArrayCount(); 94 size_t allocSize = fCount * sizeof(SkPMColor); 95 SkDEBUGCODE(bool success = false;) 96 if (buffer.validateAvailable(allocSize)) { 97 fColors = (SkPMColor*)sk_malloc_throw(allocSize); 98 SkDEBUGCODE(success =) buffer.readColorArray(fColors, fCount); 99 } else { 100 fCount = 0; 101 fColors = NULL; 102 } 103 #ifdef SK_DEBUG 104 SkASSERT((unsigned)fCount <= 256); 105 SkASSERT(success); 106 #endif 107 } 108 109 void SkColorTable::writeToBuffer(SkWriteBuffer& buffer) const { 110 buffer.writeUInt(fAlphaType); 111 buffer.writeColorArray(fColors, fCount); 112 } 113