• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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  */
16 
17 #include "SkBitmap.h"
18 #include "SkFlattenable.h"
19 #include "SkStream.h"
20 #include "SkTemplates.h"
21 
SkColorTable(int count)22 SkColorTable::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));
33 
34     SkDEBUGCODE(fColorLockCount = 0;)
35     SkDEBUGCODE(f16BitCacheLockCount = 0;)
36 }
37 
38 // call SkRefCnt's constructor explicitly, to avoid warning
SkColorTable(const SkColorTable & src)39 SkColorTable::SkColorTable(const SkColorTable& src) : SkRefCnt() {
40     f16BitCache = NULL;
41     fFlags = src.fFlags;
42     int count = src.count();
43     fCount = SkToU16(count);
44     fColors = reinterpret_cast<SkPMColor*>(
45                                     sk_malloc_throw(count * sizeof(SkPMColor)));
46     memcpy(fColors, src.fColors, count * sizeof(SkPMColor));
47 
48     SkDEBUGCODE(fColorLockCount = 0;)
49     SkDEBUGCODE(f16BitCacheLockCount = 0;)
50 }
51 
SkColorTable(const SkPMColor colors[],int count)52 SkColorTable::SkColorTable(const SkPMColor colors[], int count)
53     : f16BitCache(NULL), fFlags(0)
54 {
55     if (count < 0)
56         count = 0;
57     else if (count > 256)
58         count = 256;
59 
60     fCount = SkToU16(count);
61     fColors = reinterpret_cast<SkPMColor*>(
62                                     sk_malloc_throw(count * sizeof(SkPMColor)));
63 
64     if (colors)
65         memcpy(fColors, colors, count * sizeof(SkPMColor));
66 
67     SkDEBUGCODE(fColorLockCount = 0;)
68     SkDEBUGCODE(f16BitCacheLockCount = 0;)
69 }
70 
~SkColorTable()71 SkColorTable::~SkColorTable()
72 {
73     SkASSERT(fColorLockCount == 0);
74     SkASSERT(f16BitCacheLockCount == 0);
75 
76     sk_free(fColors);
77     sk_free(f16BitCache);
78 }
79 
setFlags(unsigned flags)80 void SkColorTable::setFlags(unsigned flags)
81 {
82     fFlags = SkToU8(flags);
83 }
84 
unlockColors(bool changed)85 void SkColorTable::unlockColors(bool changed)
86 {
87     SkASSERT(fColorLockCount != 0);
88     SkDEBUGCODE(fColorLockCount -= 1;)
89     if (changed)
90         this->inval16BitCache();
91 }
92 
inval16BitCache()93 void SkColorTable::inval16BitCache()
94 {
95     SkASSERT(f16BitCacheLockCount == 0);
96     if (f16BitCache)
97     {
98         sk_free(f16BitCache);
99         f16BitCache = NULL;
100     }
101 }
102 
103 #include "SkColorPriv.h"
104 
build_16bitcache(uint16_t dst[],const SkPMColor src[],int count)105 static inline void build_16bitcache(uint16_t dst[], const SkPMColor src[], int count)
106 {
107     while (--count >= 0)
108         *dst++ = SkPixel32ToPixel16_ToU16(*src++);
109 }
110 
lock16BitCache()111 const uint16_t* SkColorTable::lock16BitCache()
112 {
113     if (fFlags & kColorsAreOpaque_Flag)
114     {
115         if (f16BitCache == NULL) // build the cache
116         {
117             f16BitCache = (uint16_t*)sk_malloc_throw(fCount * sizeof(uint16_t));
118             build_16bitcache(f16BitCache, fColors, fCount);
119         }
120     }
121     else    // our colors have alpha, so no cache
122     {
123         this->inval16BitCache();
124         if (f16BitCache)
125         {
126             sk_free(f16BitCache);
127             f16BitCache = NULL;
128         }
129     }
130 
131     SkDEBUGCODE(f16BitCacheLockCount += 1);
132     return f16BitCache;
133 }
134 
setIsOpaque(bool isOpaque)135 void SkColorTable::setIsOpaque(bool isOpaque) {
136     if (isOpaque) {
137         fFlags |= kColorsAreOpaque_Flag;
138     } else {
139         fFlags &= ~kColorsAreOpaque_Flag;
140     }
141 }
142 
143 ///////////////////////////////////////////////////////////////////////////////
144 
SkColorTable(SkFlattenableReadBuffer & buffer)145 SkColorTable::SkColorTable(SkFlattenableReadBuffer& buffer) {
146     f16BitCache = NULL;
147     SkDEBUGCODE(fColorLockCount = 0;)
148     SkDEBUGCODE(f16BitCacheLockCount = 0;)
149 
150     fCount = buffer.readU16();
151     SkASSERT((unsigned)fCount <= 256);
152 
153     fFlags = buffer.readU8();
154 
155     fColors = (SkPMColor*)sk_malloc_throw(fCount * sizeof(SkPMColor));
156     buffer.read(fColors, fCount * sizeof(SkPMColor));
157 }
158 
flatten(SkFlattenableWriteBuffer & buffer) const159 void SkColorTable::flatten(SkFlattenableWriteBuffer& buffer) const {
160     int count = this->count();
161     buffer.write16(count);
162     buffer.write8(this->getFlags());
163     buffer.writeMul4(fColors, count * sizeof(SkPMColor));
164 }
165 
166