1 :
2 : /*
3 : * Copyright 2009 The Android Open Source Project
4 : *
5 : * Use of this source code is governed by a BSD-style license that can be
6 : * found in the LICENSE file.
7 : */
8 :
9 :
10 : #include "SkBitmap.h"
11 : #include "SkFlattenable.h"
12 : #include "SkStream.h"
13 : #include "SkTemplates.h"
14 :
15 0 : SkColorTable::SkColorTable(int count)
16 0 : : f16BitCache(NULL), fFlags(0)
17 : {
18 0 : if (count < 0)
19 0 : count = 0;
20 0 : else if (count > 256)
21 0 : count = 256;
22 :
23 0 : fCount = SkToU16(count);
24 0 : fColors = (SkPMColor*)sk_malloc_throw(count * sizeof(SkPMColor));
25 0 : memset(fColors, 0, count * sizeof(SkPMColor));
26 :
27 0 : SkDEBUGCODE(fColorLockCount = 0;)
28 0 : SkDEBUGCODE(f16BitCacheLockCount = 0;)
29 0 : }
30 :
31 : // call SkRefCnt's constructor explicitly, to avoid warning
32 0 : SkColorTable::SkColorTable(const SkColorTable& src) : SkRefCnt() {
33 0 : f16BitCache = NULL;
34 0 : fFlags = src.fFlags;
35 0 : int count = src.count();
36 0 : fCount = SkToU16(count);
37 : fColors = reinterpret_cast<SkPMColor*>(
38 0 : sk_malloc_throw(count * sizeof(SkPMColor)));
39 0 : memcpy(fColors, src.fColors, count * sizeof(SkPMColor));
40 :
41 0 : SkDEBUGCODE(fColorLockCount = 0;)
42 0 : SkDEBUGCODE(f16BitCacheLockCount = 0;)
43 0 : }
44 :
45 0 : SkColorTable::SkColorTable(const SkPMColor colors[], int count)
46 0 : : f16BitCache(NULL), fFlags(0)
47 : {
48 0 : if (count < 0)
49 0 : count = 0;
50 0 : else if (count > 256)
51 0 : count = 256;
52 :
53 0 : fCount = SkToU16(count);
54 : fColors = reinterpret_cast<SkPMColor*>(
55 0 : sk_malloc_throw(count * sizeof(SkPMColor)));
56 :
57 0 : if (colors)
58 0 : memcpy(fColors, colors, count * sizeof(SkPMColor));
59 :
60 0 : SkDEBUGCODE(fColorLockCount = 0;)
61 0 : SkDEBUGCODE(f16BitCacheLockCount = 0;)
62 0 : }
63 :
64 0 : SkColorTable::~SkColorTable()
65 : {
66 0 : SkASSERT(fColorLockCount == 0);
67 0 : SkASSERT(f16BitCacheLockCount == 0);
68 :
69 0 : sk_free(fColors);
70 0 : sk_free(f16BitCache);
71 0 : }
72 :
73 0 : void SkColorTable::setFlags(unsigned flags)
74 : {
75 0 : fFlags = SkToU8(flags);
76 0 : }
77 :
78 0 : void SkColorTable::unlockColors(bool changed)
79 : {
80 0 : SkASSERT(fColorLockCount != 0);
81 0 : SkDEBUGCODE(fColorLockCount -= 1;)
82 0 : if (changed)
83 0 : this->inval16BitCache();
84 0 : }
85 :
86 0 : void SkColorTable::inval16BitCache()
87 : {
88 0 : SkASSERT(f16BitCacheLockCount == 0);
89 0 : if (f16BitCache)
90 : {
91 0 : sk_free(f16BitCache);
92 0 : f16BitCache = NULL;
93 : }
94 0 : }
95 :
96 : #include "SkColorPriv.h"
97 :
98 0 : static inline void build_16bitcache(uint16_t dst[], const SkPMColor src[], int count)
99 : {
100 0 : while (--count >= 0)
101 0 : *dst++ = SkPixel32ToPixel16_ToU16(*src++);
102 0 : }
103 :
104 0 : const uint16_t* SkColorTable::lock16BitCache()
105 : {
106 0 : if (fFlags & kColorsAreOpaque_Flag)
107 : {
108 0 : if (f16BitCache == NULL) // build the cache
109 : {
110 0 : f16BitCache = (uint16_t*)sk_malloc_throw(fCount * sizeof(uint16_t));
111 0 : build_16bitcache(f16BitCache, fColors, fCount);
112 : }
113 : }
114 : else // our colors have alpha, so no cache
115 : {
116 0 : this->inval16BitCache();
117 0 : if (f16BitCache)
118 : {
119 0 : sk_free(f16BitCache);
120 0 : f16BitCache = NULL;
121 : }
122 : }
123 :
124 0 : SkDEBUGCODE(f16BitCacheLockCount += 1);
125 0 : return f16BitCache;
126 : }
127 :
128 0 : void SkColorTable::setIsOpaque(bool isOpaque) {
129 0 : if (isOpaque) {
130 0 : fFlags |= kColorsAreOpaque_Flag;
131 : } else {
132 0 : fFlags &= ~kColorsAreOpaque_Flag;
133 : }
134 0 : }
135 :
136 : ///////////////////////////////////////////////////////////////////////////////
137 :
138 0 : SkColorTable::SkColorTable(SkFlattenableReadBuffer& buffer) {
139 0 : f16BitCache = NULL;
140 0 : SkDEBUGCODE(fColorLockCount = 0;)
141 0 : SkDEBUGCODE(f16BitCacheLockCount = 0;)
142 :
143 0 : fCount = buffer.readU16();
144 0 : SkASSERT((unsigned)fCount <= 256);
145 :
146 0 : fFlags = buffer.readU8();
147 :
148 0 : fColors = (SkPMColor*)sk_malloc_throw(fCount * sizeof(SkPMColor));
149 0 : buffer.read(fColors, fCount * sizeof(SkPMColor));
150 0 : }
151 :
152 0 : void SkColorTable::flatten(SkFlattenableWriteBuffer& buffer) const {
153 0 : int count = this->count();
154 0 : buffer.write16(count);
155 0 : buffer.write8(this->getFlags());
156 0 : buffer.writeMul4(fColors, count * sizeof(SkPMColor));
157 0 : }
158 :
|