11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 211285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed/* 31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2009 The Android Open Source Project 411285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed * 51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be 61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file. 711285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed */ 80910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 91cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkBitmap.h" 110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkFlattenable.h" 120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkStream.h" 130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkTemplates.h" 140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkColorTable::SkColorTable(int count) 160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project : f16BitCache(NULL), fFlags(0) 170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (count < 0) 190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project count = 0; 200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project else if (count > 256) 210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project count = 256; 220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fCount = SkToU16(count); 240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fColors = (SkPMColor*)sk_malloc_throw(count * sizeof(SkPMColor)); 250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project memset(fColors, 0, count * sizeof(SkPMColor)); 2611285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed 2711285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed SkDEBUGCODE(fColorLockCount = 0;) 2811285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed SkDEBUGCODE(f16BitCacheLockCount = 0;) 2911285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed} 3011285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed 31dab163f0b2658c2dba48839e72f81d3d8ee0ae8bMike Reed// call SkRefCnt's constructor explicitly, to avoid warning 32dab163f0b2658c2dba48839e72f81d3d8ee0ae8bMike ReedSkColorTable::SkColorTable(const SkColorTable& src) : SkRefCnt() { 3311285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed f16BitCache = NULL; 3411285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed fFlags = src.fFlags; 3511285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed int count = src.count(); 3611285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed fCount = SkToU16(count); 3711285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed fColors = reinterpret_cast<SkPMColor*>( 3811285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed sk_malloc_throw(count * sizeof(SkPMColor))); 3911285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed memcpy(fColors, src.fColors, count * sizeof(SkPMColor)); 4011285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed 410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDEBUGCODE(fColorLockCount = 0;) 420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDEBUGCODE(f16BitCacheLockCount = 0;) 430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkColorTable::SkColorTable(const SkPMColor colors[], int count) 460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project : f16BitCache(NULL), fFlags(0) 470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (count < 0) 490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project count = 0; 500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project else if (count > 256) 510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project count = 256; 5211285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed 530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fCount = SkToU16(count); 5411285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed fColors = reinterpret_cast<SkPMColor*>( 5511285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed sk_malloc_throw(count * sizeof(SkPMColor))); 5611285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed 570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (colors) 580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project memcpy(fColors, colors, count * sizeof(SkPMColor)); 5911285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed 600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDEBUGCODE(fColorLockCount = 0;) 610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDEBUGCODE(f16BitCacheLockCount = 0;) 620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkColorTable::~SkColorTable() 650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(fColorLockCount == 0); 670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(f16BitCacheLockCount == 0); 680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_free(fColors); 700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_free(f16BitCache); 710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkColorTable::setFlags(unsigned flags) 740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fFlags = SkToU8(flags); 760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkColorTable::unlockColors(bool changed) 790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(fColorLockCount != 0); 810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDEBUGCODE(fColorLockCount -= 1;) 820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (changed) 830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project this->inval16BitCache(); 840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkColorTable::inval16BitCache() 870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(f16BitCacheLockCount == 0); 890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (f16BitCache) 900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_free(f16BitCache); 920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project f16BitCache = NULL; 930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkColorPriv.h" 970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic inline void build_16bitcache(uint16_t dst[], const SkPMColor src[], int count) 990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 1000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project while (--count >= 0) 1010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *dst++ = SkPixel32ToPixel16_ToU16(*src++); 1020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectconst uint16_t* SkColorTable::lock16BitCache() 1050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 1060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (fFlags & kColorsAreOpaque_Flag) 1070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 1080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (f16BitCache == NULL) // build the cache 1090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 1100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project f16BitCache = (uint16_t*)sk_malloc_throw(fCount * sizeof(uint16_t)); 1110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project build_16bitcache(f16BitCache, fColors, fCount); 1120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project else // our colors have alpha, so no cache 1150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 1160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project this->inval16BitCache(); 1170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (f16BitCache) 1180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 1190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_free(f16BitCache); 1200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project f16BitCache = NULL; 1210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDEBUGCODE(f16BitCacheLockCount += 1); 1250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return f16BitCache; 1260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1283026a9ec59b285412941d278a570e382088f8adaMike Reedvoid SkColorTable::setIsOpaque(bool isOpaque) { 1293026a9ec59b285412941d278a570e382088f8adaMike Reed if (isOpaque) { 1303026a9ec59b285412941d278a570e382088f8adaMike Reed fFlags |= kColorsAreOpaque_Flag; 1313026a9ec59b285412941d278a570e382088f8adaMike Reed } else { 1323026a9ec59b285412941d278a570e382088f8adaMike Reed fFlags &= ~kColorsAreOpaque_Flag; 1333026a9ec59b285412941d278a570e382088f8adaMike Reed } 1343026a9ec59b285412941d278a570e382088f8adaMike Reed} 1353026a9ec59b285412941d278a570e382088f8adaMike Reed 1360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 1370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkColorTable::SkColorTable(SkFlattenableReadBuffer& buffer) { 1390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project f16BitCache = NULL; 1400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDEBUGCODE(fColorLockCount = 0;) 1410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDEBUGCODE(f16BitCacheLockCount = 0;) 1420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fCount = buffer.readU16(); 1440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT((unsigned)fCount <= 256); 1450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fFlags = buffer.readU8(); 1470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fColors = (SkPMColor*)sk_malloc_throw(fCount * sizeof(SkPMColor)); 1490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project buffer.read(fColors, fCount * sizeof(SkPMColor)); 1500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkColorTable::flatten(SkFlattenableWriteBuffer& buffer) const { 1530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int count = this->count(); 1540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project buffer.write16(count); 1550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project buffer.write8(this->getFlags()); 1560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project buffer.writeMul4(fColors, count * sizeof(SkPMColor)); 1570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 159