1/*
2 * Copyright 2009 The Android Open Source Project
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8
9#include "SkColorTable.h"
10#include "SkReadBuffer.h"
11#include "SkWriteBuffer.h"
12#include "SkStream.h"
13#include "SkTemplates.h"
14
15void SkColorTable::init(const SkPMColor colors[], int count) {
16    SkASSERT((unsigned)count <= 256);
17
18    fCount = count;
19    fColors = reinterpret_cast<SkPMColor*>(sk_malloc_throw(count * sizeof(SkPMColor)));
20
21    memcpy(fColors, colors, count * sizeof(SkPMColor));
22}
23
24SkColorTable::SkColorTable(const SkPMColor colors[], int count) {
25    SkASSERT(0 == count || colors);
26    if (count < 0) {
27        count = 0;
28    } else if (count > 256) {
29        count = 256;
30    }
31    this->init(colors, count);
32}
33
34SkColorTable::SkColorTable(SkPMColor* colors, int count, AllocatedWithMalloc)
35    : fColors(colors)
36    , fCount(count)
37{
38    SkASSERT(count > 0 && count <= 256);
39    SkASSERT(colors);
40}
41
42SkColorTable::~SkColorTable() {
43    sk_free(fColors);
44    sk_free(f16BitCache);
45}
46
47#include "SkColorPriv.h"
48
49const uint16_t* SkColorTable::read16BitCache() const {
50    f16BitCacheOnce([this] {
51        f16BitCache = (uint16_t*)sk_malloc_throw(fCount * sizeof(uint16_t));
52        for (int i = 0; i < fCount; i++) {
53            f16BitCache[i] = SkPixel32ToPixel16_ToU16(fColors[i]);
54        }
55    });
56    return f16BitCache;
57}
58
59///////////////////////////////////////////////////////////////////////////////
60
61#if 0
62SkColorTable::SkColorTable(SkReadBuffer& buffer) {
63    if (buffer.isVersionLT(SkReadBuffer::kRemoveColorTableAlpha_Version)) {
64        /*fAlphaType = */buffer.readUInt();
65    }
66
67    fCount = buffer.getArrayCount();
68    size_t allocSize = fCount * sizeof(SkPMColor);
69    SkDEBUGCODE(bool success = false;)
70    if (buffer.validateAvailable(allocSize)) {
71        fColors = (SkPMColor*)sk_malloc_throw(allocSize);
72        SkDEBUGCODE(success =) buffer.readColorArray(fColors, fCount);
73    } else {
74        fCount = 0;
75        fColors = nullptr;
76    }
77#ifdef SK_DEBUG
78    SkASSERT((unsigned)fCount <= 256);
79    SkASSERT(success);
80#endif
81}
82#endif
83
84void SkColorTable::writeToBuffer(SkWriteBuffer& buffer) const {
85    buffer.writeColorArray(fColors, fCount);
86}
87
88SkColorTable* SkColorTable::Create(SkReadBuffer& buffer) {
89    if (buffer.isVersionLT(SkReadBuffer::kRemoveColorTableAlpha_Version)) {
90        /*fAlphaType = */buffer.readUInt();
91    }
92
93    const int count = buffer.getArrayCount();
94    if (0 == count) {
95        return new SkColorTable(nullptr, 0);
96    }
97
98    if (count < 0 || count > 256) {
99        buffer.validate(false);
100        return nullptr;
101    }
102
103    const size_t allocSize = count * sizeof(SkPMColor);
104    std::unique_ptr<SkPMColor> colors((SkPMColor*)sk_malloc_throw(allocSize));
105    if (!buffer.readColorArray(colors.get(), count)) {
106        return nullptr;
107    }
108
109    return new SkColorTable(colors.release(), count, kAllocatedWithMalloc);
110}
111