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 "SkColorTable.h"
11 #include "SkReadBuffer.h"
12 #include "SkWriteBuffer.h"
13 #include "SkStream.h"
14 #include "SkTemplates.h"
15 
init(const SkPMColor colors[],int count)16 void SkColorTable::init(const SkPMColor colors[], int count) {
17     SkASSERT((unsigned)count <= 256);
18 
19     fCount = count;
20     fColors = reinterpret_cast<SkPMColor*>(sk_malloc_throw(count * sizeof(SkPMColor)));
21 
22     memcpy(fColors, colors, count * sizeof(SkPMColor));
23 }
24 
SkColorTable(const SkPMColor colors[],int count)25 SkColorTable::SkColorTable(const SkPMColor colors[], int count) {
26     SkASSERT(0 == count || colors);
27     if (count < 0) {
28         count = 0;
29     } else if (count > 256) {
30         count = 256;
31     }
32     this->init(colors, count);
33 }
34 
SkColorTable(SkPMColor * colors,int count,AllocatedWithMalloc)35 SkColorTable::SkColorTable(SkPMColor* colors, int count, AllocatedWithMalloc)
36     : fColors(colors)
37     , fCount(count)
38 {
39     SkASSERT(count > 0 && count <= 256);
40     SkASSERT(colors);
41 }
42 
~SkColorTable()43 SkColorTable::~SkColorTable() {
44     sk_free(fColors);
45     // f16BitCache frees itself
46 }
47 
48 #include "SkColorPriv.h"
49 
read16BitCache() const50 const uint16_t* SkColorTable::read16BitCache() const {
51     return f16BitCache.get([&]{
52         auto cache = new uint16_t[fCount];
53         for (int i = 0; i < fCount; i++) {
54             cache[i] = SkPixel32ToPixel16_ToU16(fColors[i]);
55         }
56         return cache;
57     });
58 }
59 
60 ///////////////////////////////////////////////////////////////////////////////
61 
62 #if 0
63 SkColorTable::SkColorTable(SkReadBuffer& buffer) {
64     if (buffer.isVersionLT(SkReadBuffer::kRemoveColorTableAlpha_Version)) {
65         /*fAlphaType = */buffer.readUInt();
66     }
67 
68     fCount = buffer.getArrayCount();
69     size_t allocSize = fCount * sizeof(SkPMColor);
70     SkDEBUGCODE(bool success = false;)
71     if (buffer.validateAvailable(allocSize)) {
72         fColors = (SkPMColor*)sk_malloc_throw(allocSize);
73         SkDEBUGCODE(success =) buffer.readColorArray(fColors, fCount);
74     } else {
75         fCount = 0;
76         fColors = nullptr;
77     }
78 #ifdef SK_DEBUG
79     SkASSERT((unsigned)fCount <= 256);
80     SkASSERT(success);
81 #endif
82 }
83 #endif
84 
writeToBuffer(SkWriteBuffer & buffer) const85 void SkColorTable::writeToBuffer(SkWriteBuffer& buffer) const {
86     buffer.writeColorArray(fColors, fCount);
87 }
88 
Create(SkReadBuffer & buffer)89 SkColorTable* SkColorTable::Create(SkReadBuffer& buffer) {
90     if (buffer.isVersionLT(SkReadBuffer::kRemoveColorTableAlpha_Version)) {
91         /*fAlphaType = */buffer.readUInt();
92     }
93 
94     const int count = buffer.getArrayCount();
95     if (0 == count) {
96         return new SkColorTable(nullptr, 0);
97     }
98 
99     if (count < 0 || count > 256) {
100         buffer.validate(false);
101         return nullptr;
102     }
103 
104     const size_t allocSize = count * sizeof(SkPMColor);
105     SkAutoTDelete<SkPMColor> colors((SkPMColor*)sk_malloc_throw(allocSize));
106     if (!buffer.readColorArray(colors, count)) {
107         return nullptr;
108     }
109 
110     return new SkColorTable(colors.detach(), count, kAllocatedWithMalloc);
111 }
112 
113