180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2009 The Android Open Source Project
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkColorTable.h"
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkFlattenableBuffers.h"
1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkStream.h"
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkTemplates.h"
1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// As copy constructor is hidden in the class hierarchy, we need to call
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// default constructor explicitly to suppress a compiler warning.
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkColorTable::SkColorTable(const SkColorTable& src) : INHERITED() {
1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    f16BitCache = NULL;
190a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    fAlphaType = src.fAlphaType;
2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int count = src.count();
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fCount = SkToU16(count);
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fColors = reinterpret_cast<SkPMColor*>(
2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                    sk_malloc_throw(count * sizeof(SkPMColor)));
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    memcpy(fColors, src.fColors, count * sizeof(SkPMColor));
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDEBUGCODE(fColorLockCount = 0;)
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDEBUGCODE(f16BitCacheLockCount = 0;)
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
300a657bbc2c6fc9daf699942e023050536d5ec95fDerek SollenbergerSkColorTable::SkColorTable(const SkPMColor colors[], int count, SkAlphaType at)
310a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    : f16BitCache(NULL), fAlphaType(SkToU8(at))
3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
330a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkASSERT(0 == count || NULL != colors);
340a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
350a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    if (count < 0) {
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        count = 0;
370a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    } else if (count > 256) {
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        count = 256;
390a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fCount = SkToU16(count);
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fColors = reinterpret_cast<SkPMColor*>(
4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                    sk_malloc_throw(count * sizeof(SkPMColor)));
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
450a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    memcpy(fColors, colors, count * sizeof(SkPMColor));
4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDEBUGCODE(fColorLockCount = 0;)
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDEBUGCODE(f16BitCacheLockCount = 0;)
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkColorTable::~SkColorTable()
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(fColorLockCount == 0);
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(f16BitCacheLockCount == 0);
5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    sk_free(fColors);
5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    sk_free(f16BitCache);
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
600a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergervoid SkColorTable::unlockColors() {
6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(fColorLockCount != 0);
6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDEBUGCODE(sk_atomic_dec(&fColorLockCount);)
6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkColorPriv.h"
6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
670a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerstatic inline void build_16bitcache(uint16_t dst[], const SkPMColor src[],
680a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                                    int count) {
690a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    while (--count >= 0) {
7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        *dst++ = SkPixel32ToPixel16_ToU16(*src++);
710a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
740a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerconst uint16_t* SkColorTable::lock16BitCache() {
750a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    if (this->isOpaque() && NULL == f16BitCache) {
760a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        f16BitCache = (uint16_t*)sk_malloc_throw(fCount * sizeof(uint16_t));
770a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        build_16bitcache(f16BitCache, fColors, fCount);
7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDEBUGCODE(f16BitCacheLockCount += 1);
8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return f16BitCache;
8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru///////////////////////////////////////////////////////////////////////////////
8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkColorTable::SkColorTable(SkFlattenableReadBuffer& buffer) {
8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    f16BitCache = NULL;
8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDEBUGCODE(fColorLockCount = 0;)
8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkDEBUGCODE(f16BitCacheLockCount = 0;)
9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
910a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    fAlphaType = SkToU8(buffer.readUInt());
9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fCount = buffer.getArrayCount();
9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fColors = (SkPMColor*)sk_malloc_throw(fCount * sizeof(SkPMColor));
940a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkDEBUGCODE(bool success =) buffer.readColorArray(fColors, fCount);
95d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#ifdef SK_DEBUG
9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT((unsigned)fCount <= 256);
970a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkASSERT(success);
98d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#endif
9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1010a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergervoid SkColorTable::writeToBuffer(SkFlattenableWriteBuffer& buffer) const {
1020a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    buffer.writeUInt(fAlphaType);
10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    buffer.writeColorArray(fColors, fCount);
10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
105