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