1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 2a6260ff5696e3ae45f295463eaeada2cd75a8b85reed@android.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2009 The Android Open Source Project 4a6260ff5696e3ae45f295463eaeada2cd75a8b85reed@android.com * 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 7a6260ff5696e3ae45f295463eaeada2cd75a8b85reed@android.com */ 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 1064a0ec36555352ec31aa7c5a7630a5d042b010badjsollen@google.com#include "SkColorTable.h" 118b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkReadBuffer.h" 128b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkWriteBuffer.h" 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkStream.h" 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTemplates.h" 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 162999f789c7e66a31066414f4b8fffb3148b677c5reed@google.com// As copy constructor is hidden in the class hierarchy, we need to call 172999f789c7e66a31066414f4b8fffb3148b677c5reed@google.com// default constructor explicitly to suppress a compiler warning. 182999f789c7e66a31066414f4b8fffb3148b677c5reed@google.comSkColorTable::SkColorTable(const SkColorTable& src) : INHERITED() { 19f9ab99aaade8c451c0e9309b4c61a448373019e3weita@google.com f16BitCache = NULL; 200a6151d66cc32d91eca037c91e557158cf8a2be2reed@google.com fAlphaType = src.fAlphaType; 21f9ab99aaade8c451c0e9309b4c61a448373019e3weita@google.com int count = src.count(); 22f9ab99aaade8c451c0e9309b4c61a448373019e3weita@google.com fCount = SkToU16(count); 23a6260ff5696e3ae45f295463eaeada2cd75a8b85reed@android.com fColors = reinterpret_cast<SkPMColor*>( 24a6260ff5696e3ae45f295463eaeada2cd75a8b85reed@android.com sk_malloc_throw(count * sizeof(SkPMColor))); 25f9ab99aaade8c451c0e9309b4c61a448373019e3weita@google.com memcpy(fColors, src.fColors, count * sizeof(SkPMColor)); 26f9ab99aaade8c451c0e9309b4c61a448373019e3weita@google.com 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(fColorLockCount = 0;) 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(f16BitCacheLockCount = 0;) 298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 310a6151d66cc32d91eca037c91e557158cf8a2be2reed@google.comSkColorTable::SkColorTable(const SkPMColor colors[], int count, SkAlphaType at) 320a6151d66cc32d91eca037c91e557158cf8a2be2reed@google.com : f16BitCache(NULL), fAlphaType(SkToU8(at)) 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 340a6151d66cc32d91eca037c91e557158cf8a2be2reed@google.com SkASSERT(0 == count || NULL != colors); 350a6151d66cc32d91eca037c91e557158cf8a2be2reed@google.com 360a6151d66cc32d91eca037c91e557158cf8a2be2reed@google.com if (count < 0) { 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com count = 0; 380a6151d66cc32d91eca037c91e557158cf8a2be2reed@google.com } else if (count > 256) { 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com count = 256; 400a6151d66cc32d91eca037c91e557158cf8a2be2reed@google.com } 41f9ab99aaade8c451c0e9309b4c61a448373019e3weita@google.com 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCount = SkToU16(count); 43a6260ff5696e3ae45f295463eaeada2cd75a8b85reed@android.com fColors = reinterpret_cast<SkPMColor*>( 44a6260ff5696e3ae45f295463eaeada2cd75a8b85reed@android.com sk_malloc_throw(count * sizeof(SkPMColor))); 45f9ab99aaade8c451c0e9309b4c61a448373019e3weita@google.com 460a6151d66cc32d91eca037c91e557158cf8a2be2reed@google.com memcpy(fColors, colors, count * sizeof(SkPMColor)); 47f9ab99aaade8c451c0e9309b4c61a448373019e3weita@google.com 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(fColorLockCount = 0;) 498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(f16BitCacheLockCount = 0;) 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkColorTable::~SkColorTable() 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(fColorLockCount == 0); 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(f16BitCacheLockCount == 0); 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_free(fColors); 588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_free(f16BitCache); 598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 610a6151d66cc32d91eca037c91e557158cf8a2be2reed@google.comvoid SkColorTable::unlockColors() { 628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(fColorLockCount != 0); 63c9ab987efcb7e8b69237d565f73c28c137610232djsollen@google.com SkDEBUGCODE(sk_atomic_dec(&fColorLockCount);) 648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorPriv.h" 678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 680a6151d66cc32d91eca037c91e557158cf8a2be2reed@google.comstatic inline void build_16bitcache(uint16_t dst[], const SkPMColor src[], 690a6151d66cc32d91eca037c91e557158cf8a2be2reed@google.com int count) { 700a6151d66cc32d91eca037c91e557158cf8a2be2reed@google.com while (--count >= 0) { 718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *dst++ = SkPixel32ToPixel16_ToU16(*src++); 720a6151d66cc32d91eca037c91e557158cf8a2be2reed@google.com } 738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 750a6151d66cc32d91eca037c91e557158cf8a2be2reed@google.comconst uint16_t* SkColorTable::lock16BitCache() { 760a6151d66cc32d91eca037c91e557158cf8a2be2reed@google.com if (this->isOpaque() && NULL == f16BitCache) { 770a6151d66cc32d91eca037c91e557158cf8a2be2reed@google.com f16BitCache = (uint16_t*)sk_malloc_throw(fCount * sizeof(uint16_t)); 780a6151d66cc32d91eca037c91e557158cf8a2be2reed@google.com build_16bitcache(f16BitCache, fColors, fCount); 798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(f16BitCacheLockCount += 1); 828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return f16BitCache; 838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 878b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgSkColorTable::SkColorTable(SkReadBuffer& buffer) { 888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com f16BitCache = NULL; 898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(fColorLockCount = 0;) 908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(f16BitCacheLockCount = 0;) 918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 920a6151d66cc32d91eca037c91e557158cf8a2be2reed@google.com fAlphaType = SkToU8(buffer.readUInt()); 93c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com fCount = buffer.getArrayCount(); 94ef74fa189b738e13295d6a96f86a6e10223505a8commit-bot@chromium.org size_t allocSize = fCount * sizeof(SkPMColor); 95ef74fa189b738e13295d6a96f86a6e10223505a8commit-bot@chromium.org SkDEBUGCODE(bool success = false;) 96ef74fa189b738e13295d6a96f86a6e10223505a8commit-bot@chromium.org if (buffer.validateAvailable(allocSize)) { 97ef74fa189b738e13295d6a96f86a6e10223505a8commit-bot@chromium.org fColors = (SkPMColor*)sk_malloc_throw(allocSize); 98ef74fa189b738e13295d6a96f86a6e10223505a8commit-bot@chromium.org SkDEBUGCODE(success =) buffer.readColorArray(fColors, fCount); 99ef74fa189b738e13295d6a96f86a6e10223505a8commit-bot@chromium.org } else { 100ef74fa189b738e13295d6a96f86a6e10223505a8commit-bot@chromium.org fCount = 0; 101ef74fa189b738e13295d6a96f86a6e10223505a8commit-bot@chromium.org fColors = NULL; 102ef74fa189b738e13295d6a96f86a6e10223505a8commit-bot@chromium.org } 10357313f6472684b14570562e43e84f5e2d6fcf278bsalomon@google.com#ifdef SK_DEBUG 104c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com SkASSERT((unsigned)fCount <= 256); 105025128811219dc45fd99b6c4d1d14f833cf7a26ecommit-bot@chromium.org SkASSERT(success); 10657313f6472684b14570562e43e84f5e2d6fcf278bsalomon@google.com#endif 1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1098b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgvoid SkColorTable::writeToBuffer(SkWriteBuffer& buffer) const { 1100a6151d66cc32d91eca037c91e557158cf8a2be2reed@google.com buffer.writeUInt(fAlphaType); 111c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com buffer.writeColorArray(fColors, fCount); 1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 113