SkColorTable.cpp revision 3026a9ec59b285412941d278a570e382088f8ada
111285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed/* 211285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed * Copyright (C) 2006-2009 The Android Open Source Project 311285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed * 411285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed * Licensed under the Apache License, Version 2.0 (the "License"); 511285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed * you may not use this file except in compliance with the License. 611285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed * You may obtain a copy of the License at 711285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed * 811285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed * http://www.apache.org/licenses/LICENSE-2.0 911285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed * 1011285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed * Unless required by applicable law or agreed to in writing, software 1111285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed * distributed under the License is distributed on an "AS IS" BASIS, 1211285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1311285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed * See the License for the specific language governing permissions and 1411285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed * limitations under the License. 1511285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed */ 160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkBitmap.h" 180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkFlattenable.h" 190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkStream.h" 200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkTemplates.h" 210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkColorTable::SkColorTable(int count) 230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project : f16BitCache(NULL), fFlags(0) 240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (count < 0) 260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project count = 0; 270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project else if (count > 256) 280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project count = 256; 290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fCount = SkToU16(count); 310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fColors = (SkPMColor*)sk_malloc_throw(count * sizeof(SkPMColor)); 320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project memset(fColors, 0, count * sizeof(SkPMColor)); 3311285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed 3411285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed SkDEBUGCODE(fColorLockCount = 0;) 3511285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed SkDEBUGCODE(f16BitCacheLockCount = 0;) 3611285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed} 3711285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed 38dab163f0b2658c2dba48839e72f81d3d8ee0ae8bMike Reed// call SkRefCnt's constructor explicitly, to avoid warning 39dab163f0b2658c2dba48839e72f81d3d8ee0ae8bMike ReedSkColorTable::SkColorTable(const SkColorTable& src) : SkRefCnt() { 4011285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed f16BitCache = NULL; 4111285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed fFlags = src.fFlags; 4211285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed int count = src.count(); 4311285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed fCount = SkToU16(count); 4411285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed fColors = reinterpret_cast<SkPMColor*>( 4511285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed sk_malloc_throw(count * sizeof(SkPMColor))); 4611285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed memcpy(fColors, src.fColors, count * sizeof(SkPMColor)); 4711285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed 480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDEBUGCODE(fColorLockCount = 0;) 490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDEBUGCODE(f16BitCacheLockCount = 0;) 500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkColorTable::SkColorTable(const SkPMColor colors[], int count) 530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project : f16BitCache(NULL), fFlags(0) 540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (count < 0) 560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project count = 0; 570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project else if (count > 256) 580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project count = 256; 5911285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed 600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fCount = SkToU16(count); 6111285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed fColors = reinterpret_cast<SkPMColor*>( 6211285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed sk_malloc_throw(count * sizeof(SkPMColor))); 6311285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed 640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (colors) 650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project memcpy(fColors, colors, count * sizeof(SkPMColor)); 6611285a304c143d1bdf3a1e321803cfcc8a6a938cMike Reed 670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDEBUGCODE(fColorLockCount = 0;) 680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDEBUGCODE(f16BitCacheLockCount = 0;) 690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkColorTable::~SkColorTable() 720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(fColorLockCount == 0); 740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(f16BitCacheLockCount == 0); 750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_free(fColors); 770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_free(f16BitCache); 780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkColorTable::setFlags(unsigned flags) 810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fFlags = SkToU8(flags); 830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkColorTable::unlockColors(bool changed) 860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(fColorLockCount != 0); 880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDEBUGCODE(fColorLockCount -= 1;) 890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (changed) 900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project this->inval16BitCache(); 910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkColorTable::inval16BitCache() 940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(f16BitCacheLockCount == 0); 960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (f16BitCache) 970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_free(f16BitCache); 990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project f16BitCache = NULL; 1000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkColorPriv.h" 1040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic inline void build_16bitcache(uint16_t dst[], const SkPMColor src[], int count) 1060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 1070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project while (--count >= 0) 1080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *dst++ = SkPixel32ToPixel16_ToU16(*src++); 1090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectconst uint16_t* SkColorTable::lock16BitCache() 1120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 1130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (fFlags & kColorsAreOpaque_Flag) 1140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 1150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (f16BitCache == NULL) // build the cache 1160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 1170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project f16BitCache = (uint16_t*)sk_malloc_throw(fCount * sizeof(uint16_t)); 1180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project build_16bitcache(f16BitCache, fColors, fCount); 1190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project else // our colors have alpha, so no cache 1220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 1230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project this->inval16BitCache(); 1240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (f16BitCache) 1250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 1260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_free(f16BitCache); 1270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project f16BitCache = NULL; 1280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDEBUGCODE(f16BitCacheLockCount += 1); 1320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return f16BitCache; 1330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1353026a9ec59b285412941d278a570e382088f8adaMike Reedvoid SkColorTable::setIsOpaque(bool isOpaque) { 1363026a9ec59b285412941d278a570e382088f8adaMike Reed if (isOpaque) { 1373026a9ec59b285412941d278a570e382088f8adaMike Reed fFlags |= kColorsAreOpaque_Flag; 1383026a9ec59b285412941d278a570e382088f8adaMike Reed } else { 1393026a9ec59b285412941d278a570e382088f8adaMike Reed fFlags &= ~kColorsAreOpaque_Flag; 1403026a9ec59b285412941d278a570e382088f8adaMike Reed } 1413026a9ec59b285412941d278a570e382088f8adaMike Reed} 1423026a9ec59b285412941d278a570e382088f8adaMike Reed 1430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 1440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkColorTable::SkColorTable(SkFlattenableReadBuffer& buffer) { 1460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project f16BitCache = NULL; 1470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDEBUGCODE(fColorLockCount = 0;) 1480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDEBUGCODE(f16BitCacheLockCount = 0;) 1490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fCount = buffer.readU16(); 1510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT((unsigned)fCount <= 256); 1520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fFlags = buffer.readU8(); 1540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fColors = (SkPMColor*)sk_malloc_throw(fCount * sizeof(SkPMColor)); 1560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project buffer.read(fColors, fCount * sizeof(SkPMColor)); 1570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkColorTable::flatten(SkFlattenableWriteBuffer& buffer) const { 1600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int count = this->count(); 1610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project buffer.write16(count); 1620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project buffer.write8(this->getFlags()); 1630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project buffer.writeMul4(fColors, count * sizeof(SkPMColor)); 1640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 166