1a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary/*
2a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary * Copyright 2015 Google Inc.
3a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary *
4a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary * Use of this source code is governed by a BSD-style license that can be
5a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary * found in the LICENSE file.
6a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary */
7a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary
8a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary#include "SkCodec.h"
9a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary#include "SkColorPriv.h"
10a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary#include "SkStream.h"
11a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary#include "SkCodec_wbmp.h"
12a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary
13a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary// http://en.wikipedia.org/wiki/Variable-length_quantity
14a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanarystatic bool read_mbf(SkStream* stream, uint64_t* value) {
15a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    uint64_t n = 0;
16a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    uint8_t data;
17a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    const uint64_t kLimit = 0xFE00000000000000;
18a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    SkASSERT(kLimit == ~((~static_cast<uint64_t>(0)) >> 7));
19a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    do {
20a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary        if (n & kLimit) { // Will overflow on shift by 7.
21a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary            return false;
22a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary        }
23a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary        if (stream->read(&data, 1) != 1) {
24a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary            return false;
25a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary        }
26a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary        n = (n << 7) | (data & 0x7F);
27a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    } while (data & 0x80);
28a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    *value = n;
29a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    return true;
30a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary}
31a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary
32a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanarystatic bool read_header(SkStream* stream, SkISize* size) {
33a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    uint64_t width, height;
34a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    uint16_t data;
35a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    if (stream->read(&data, 2) != 2 || data != 0) {
36a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary        return false;
37a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    }
38a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    if (!read_mbf(stream, &width) || width > 0xFFFF || !width) {
39a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary        return false;
40a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    }
41a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    if (!read_mbf(stream, &height) || width > 0xFFFF || !height) {
42a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary        return false;
43a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    }
44a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    if (size) {
45a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary        *size = SkISize::Make(SkToS32(width), SkToS32(height));
46a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    }
47a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    return true;
48a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary}
49a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary
50a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary#define BLACK SkPackARGB32NoCheck(0xFF, 0, 0, 0)
51a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary#define WHITE SkPackARGB32NoCheck(0xFF, 0xFF, 0xFF, 0xFF)
52a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary
53a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary#define GRAYSCALE_BLACK 0
54a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary#define GRAYSCALE_WHITE 0xFF
55a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary
56a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary#define RGB565_BLACK 0
57a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary#define RGB565_WHITE 0xFFFF
58a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary
59a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanarystatic SkPMColor bit_to_pmcolor(U8CPU bit) { return bit ? WHITE : BLACK; }
60a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary
61a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanarystatic uint8_t bit_to_bit(U8CPU bit) { return bit; }
62a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary
63a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanarystatic uint8_t bit_to_grayscale(U8CPU bit) {
64a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    return bit ? GRAYSCALE_WHITE : GRAYSCALE_BLACK;
65a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary}
66a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary
67a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanarystatic uint16_t bit_to_rgb565(U8CPU bit) {
68a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    return bit ? RGB565_WHITE : RGB565_BLACK;
69a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary}
70a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary
71a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanarytypedef void (*ExpandProc)(uint8_t*, const uint8_t*, int);
72a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary
73a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary// TODO(halcanary): Add this functionality (grayscale and indexed output) to
74a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary//                  SkSwizzler and use it here.
75a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanarytemplate <typename T, T (*TRANSFORM)(U8CPU)>
76a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanarystatic void expand_bits_to_T(uint8_t* dstptr, const uint8_t* src, int bits) {
77a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    T* dst = reinterpret_cast<T*>(dstptr);
78a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    int bytes = bits >> 3;
79a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    for (int i = 0; i < bytes; i++) {
80a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary        U8CPU mask = *src++;
81a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary        for (int j = 0; j < 8; j++) {
82a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary            dst[j] = TRANSFORM((mask >> (7 - j)) & 1);
83a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary        }
84a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary        dst += 8;
85a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    }
86a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    bits &= 7;
87a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    if (bits > 0) {
88a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary        U8CPU mask = *src;
89a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary        do {
90a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary            *dst++ = TRANSFORM((mask >> 7) & 1);
91a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary            mask <<= 1;
92a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary        } while (--bits != 0);
93a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    }
94a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary}
95a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary
96a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanarySkWbmpCodec::SkWbmpCodec(const SkImageInfo& info, SkStream* stream)
97a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    : INHERITED(info, stream) {}
98a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary
99a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanarySkEncodedFormat SkWbmpCodec::onGetEncodedFormat() const {
100a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    return kWBMP_SkEncodedFormat;
101a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary}
102a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary
103a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanarySkImageGenerator::Result SkWbmpCodec::onGetPixels(const SkImageInfo& info,
104a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary                                                  void* pixels,
105a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary                                                  size_t rowBytes,
106a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary                                                  const Options&,
107a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary                                                  SkPMColor ctable[],
108a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary                                                  int* ctableCount) {
109a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    SkCodec::RewindState rewindState = this->rewindIfNeeded();
110a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    if (rewindState == kCouldNotRewind_RewindState) {
111a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary        return SkImageGenerator::kCouldNotRewind;
112a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    } else if (rewindState == kRewound_RewindState) {
113a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary        (void)read_header(this->stream(), NULL);
114a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    }
115a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    if (info.dimensions() != this->getInfo().dimensions()) {
116a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary        return SkImageGenerator::kInvalidScale;
117a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    }
118a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    ExpandProc proc = NULL;
119a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    switch (info.colorType()) {
120a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary        case kGray_8_SkColorType:
121a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary            proc = expand_bits_to_T<uint8_t, bit_to_grayscale>;
122a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary            break;
123a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary        case kN32_SkColorType:
124a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary            proc = expand_bits_to_T<SkPMColor, bit_to_pmcolor>;
125a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary            break;
126a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary        case kIndex_8_SkColorType:
127a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary            ctable[0] = BLACK;
128a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary            ctable[1] = WHITE;
129a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary            *ctableCount = 2;
130a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary            proc = expand_bits_to_T<uint8_t, bit_to_bit>;
131a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary            break;
132a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary        case kRGB_565_SkColorType:
133a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary            proc = expand_bits_to_T<uint16_t, bit_to_rgb565>;
134a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary            break;
135a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary        default:
136a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary            return SkImageGenerator::kInvalidConversion;
137a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    }
138a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    SkISize size = info.dimensions();
139a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    uint8_t* dst = static_cast<uint8_t*>(pixels);
140a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    size_t srcRowBytes = SkAlign8(size.width()) >> 3;
141a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    SkAutoTMalloc<uint8_t> src(srcRowBytes);
142a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    for (int y = 0; y < size.height(); ++y) {
143a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary        if (this->stream()->read(src.get(), srcRowBytes) != srcRowBytes) {
144a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary            return SkImageGenerator::kIncompleteInput;
145a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary        }
146a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary        proc(dst, src.get(), size.width());
147a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary        dst += rowBytes;
148a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    }
149a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    return SkImageGenerator::kSuccess;
150a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary}
151a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary
152a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanarybool SkWbmpCodec::IsWbmp(SkStream* stream) {
153a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    return read_header(stream, NULL);
154a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary}
155a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary
156a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanarySkCodec* SkWbmpCodec::NewFromStream(SkStream* stream) {
1570a7e69cb9b4e3929d659891d152a2c0b59bff4e0scroggo    SkAutoTDelete<SkStream> streamDeleter(stream);
158a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    SkISize size;
159a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    if (!read_header(stream, &size)) {
160a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary        return NULL;
161a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    }
162a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary    SkImageInfo info =
163a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary            SkImageInfo::Make(size.width(), size.height(), kGray_8_SkColorType,
164a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary                              kOpaque_SkAlphaType);
1650a7e69cb9b4e3929d659891d152a2c0b59bff4e0scroggo    return SkNEW_ARGS(SkWbmpCodec, (info, streamDeleter.detach()));
166a096d7a6d03662073f4cd46f7db5fe2cf5495c36halcanary}
167