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