blob: 7c3676d3ddcbee1ba22a25e79af2bb54dcae2212 [file] [log] [blame]
reed@android.coma6260ff2009-05-04 18:52:54 +00001/*
2 * Copyright (C) 2006-2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
reed@android.com8a1c16f2008-12-17 15:59:43 +000016
17#include "SkBitmap.h"
18#include "SkFlattenable.h"
19#include "SkStream.h"
20#include "SkTemplates.h"
21
22SkColorTable::SkColorTable(int count)
23 : f16BitCache(NULL), fFlags(0)
24{
25 if (count < 0)
26 count = 0;
27 else if (count > 256)
28 count = 256;
29
30 fCount = SkToU16(count);
31 fColors = (SkPMColor*)sk_malloc_throw(count * sizeof(SkPMColor));
32 memset(fColors, 0, count * sizeof(SkPMColor));
weita@google.comf9ab99a2009-05-03 18:23:30 +000033
34 SkDEBUGCODE(fColorLockCount = 0;)
35 SkDEBUGCODE(f16BitCacheLockCount = 0;)
36}
37
38SkColorTable::SkColorTable(const SkColorTable& src) {
39 f16BitCache = NULL;
40 fFlags = src.fFlags;
41 int count = src.count();
42 fCount = SkToU16(count);
reed@android.coma6260ff2009-05-04 18:52:54 +000043 fColors = reinterpret_cast<SkPMColor*>(
44 sk_malloc_throw(count * sizeof(SkPMColor)));
weita@google.comf9ab99a2009-05-03 18:23:30 +000045 memcpy(fColors, src.fColors, count * sizeof(SkPMColor));
46
reed@android.com8a1c16f2008-12-17 15:59:43 +000047 SkDEBUGCODE(fColorLockCount = 0;)
48 SkDEBUGCODE(f16BitCacheLockCount = 0;)
49}
50
51SkColorTable::SkColorTable(const SkPMColor colors[], int count)
52 : f16BitCache(NULL), fFlags(0)
53{
54 if (count < 0)
55 count = 0;
56 else if (count > 256)
57 count = 256;
weita@google.comf9ab99a2009-05-03 18:23:30 +000058
reed@android.com8a1c16f2008-12-17 15:59:43 +000059 fCount = SkToU16(count);
reed@android.coma6260ff2009-05-04 18:52:54 +000060 fColors = reinterpret_cast<SkPMColor*>(
61 sk_malloc_throw(count * sizeof(SkPMColor)));
weita@google.comf9ab99a2009-05-03 18:23:30 +000062
reed@android.com8a1c16f2008-12-17 15:59:43 +000063 if (colors)
64 memcpy(fColors, colors, count * sizeof(SkPMColor));
weita@google.comf9ab99a2009-05-03 18:23:30 +000065
reed@android.com8a1c16f2008-12-17 15:59:43 +000066 SkDEBUGCODE(fColorLockCount = 0;)
67 SkDEBUGCODE(f16BitCacheLockCount = 0;)
68}
69
70SkColorTable::~SkColorTable()
71{
72 SkASSERT(fColorLockCount == 0);
73 SkASSERT(f16BitCacheLockCount == 0);
74
75 sk_free(fColors);
76 sk_free(f16BitCache);
77}
78
79void SkColorTable::setFlags(unsigned flags)
80{
81 fFlags = SkToU8(flags);
82}
83
84void SkColorTable::unlockColors(bool changed)
85{
86 SkASSERT(fColorLockCount != 0);
87 SkDEBUGCODE(fColorLockCount -= 1;)
88 if (changed)
89 this->inval16BitCache();
90}
91
92void SkColorTable::inval16BitCache()
93{
94 SkASSERT(f16BitCacheLockCount == 0);
95 if (f16BitCache)
96 {
97 sk_free(f16BitCache);
98 f16BitCache = NULL;
99 }
100}
101
102#include "SkColorPriv.h"
103
104static inline void build_16bitcache(uint16_t dst[], const SkPMColor src[], int count)
105{
106 while (--count >= 0)
107 *dst++ = SkPixel32ToPixel16_ToU16(*src++);
108}
109
110const uint16_t* SkColorTable::lock16BitCache()
111{
112 if (fFlags & kColorsAreOpaque_Flag)
113 {
114 if (f16BitCache == NULL) // build the cache
115 {
116 f16BitCache = (uint16_t*)sk_malloc_throw(fCount * sizeof(uint16_t));
117 build_16bitcache(f16BitCache, fColors, fCount);
118 }
119 }
120 else // our colors have alpha, so no cache
121 {
122 this->inval16BitCache();
123 if (f16BitCache)
124 {
125 sk_free(f16BitCache);
126 f16BitCache = NULL;
127 }
128 }
129
130 SkDEBUGCODE(f16BitCacheLockCount += 1);
131 return f16BitCache;
132}
133
134///////////////////////////////////////////////////////////////////////////////
135
136SkColorTable::SkColorTable(SkFlattenableReadBuffer& buffer) {
137 f16BitCache = NULL;
138 SkDEBUGCODE(fColorLockCount = 0;)
139 SkDEBUGCODE(f16BitCacheLockCount = 0;)
140
141 fCount = buffer.readU16();
142 SkASSERT((unsigned)fCount <= 256);
143
144 fFlags = buffer.readU8();
145
146 fColors = (SkPMColor*)sk_malloc_throw(fCount * sizeof(SkPMColor));
147 buffer.read(fColors, fCount * sizeof(SkPMColor));
148}
149
150void SkColorTable::flatten(SkFlattenableWriteBuffer& buffer) const {
151 int count = this->count();
152 buffer.write16(count);
153 buffer.write8(this->getFlags());
154 buffer.writeMul4(fColors, count * sizeof(SkPMColor));
155}
156