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