blob: 3036f337b7f02b21803c70ff6b4ae3895d20edd0 [file] [log] [blame]
msarett4ab9d5f2015-08-06 15:34:42 -07001/*
2 * Copyright 2015 Google Inc.
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#include "SkBmpMaskCodec.h"
9#include "SkCodecPriv.h"
10#include "SkColorPriv.h"
11
12/*
msarett4ab9d5f2015-08-06 15:34:42 -070013 * Creates an instance of the decoder
14 */
15SkBmpMaskCodec::SkBmpMaskCodec(const SkImageInfo& info, SkStream* stream,
16 uint16_t bitsPerPixel, SkMasks* masks,
msarett5406d6f2015-08-31 06:55:13 -070017 SkScanlineDecoder::SkScanlineOrder rowOrder)
msarett4ab9d5f2015-08-06 15:34:42 -070018 : INHERITED(info, stream, bitsPerPixel, rowOrder)
19 , fMasks(masks)
halcanary96fcdcc2015-08-27 07:41:13 -070020 , fMaskSwizzler(nullptr)
msarett5406d6f2015-08-31 06:55:13 -070021 , fSrcRowBytes(SkAlign4(compute_row_bytes(this->getInfo().width(), this->bitsPerPixel())))
22 , fSrcBuffer(new uint8_t [fSrcRowBytes])
msarett4ab9d5f2015-08-06 15:34:42 -070023{}
24
25/*
26 * Initiates the bitmap decode
27 */
28SkCodec::Result SkBmpMaskCodec::onGetPixels(const SkImageInfo& dstInfo,
29 void* dst, size_t dstRowBytes,
30 const Options& opts,
31 SkPMColor* inputColorPtr,
32 int* inputColorCount) {
scroggob427db12015-08-12 07:24:13 -070033 if (!this->rewindIfNeeded()) {
msarett4ab9d5f2015-08-06 15:34:42 -070034 return kCouldNotRewind;
35 }
36 if (opts.fSubset) {
37 // Subsets are not supported.
38 return kUnimplemented;
39 }
40 if (dstInfo.dimensions() != this->getInfo().dimensions()) {
41 SkCodecPrintf("Error: scaling not supported.\n");
42 return kInvalidScale;
43 }
44
45 if (!conversion_possible(dstInfo, this->getInfo())) {
46 SkCodecPrintf("Error: cannot convert input type to output type.\n");
47 return kInvalidConversion;
48 }
49
msarett5406d6f2015-08-31 06:55:13 -070050 Result result = this->prepareToDecode(dstInfo, opts, inputColorPtr, inputColorCount);
51 if (kSuccess != result) {
52 return result;
msarett4ab9d5f2015-08-06 15:34:42 -070053 }
54
msarett5406d6f2015-08-31 06:55:13 -070055 return this->decodeRows(dstInfo, dst, dstRowBytes, opts);
msarett4ab9d5f2015-08-06 15:34:42 -070056}
57
58bool SkBmpMaskCodec::initializeSwizzler(const SkImageInfo& dstInfo) {
msarett4ab9d5f2015-08-06 15:34:42 -070059 // Create the swizzler
60 fMaskSwizzler.reset(SkMaskSwizzler::CreateMaskSwizzler(
msarett5406d6f2015-08-31 06:55:13 -070061 dstInfo, this->getInfo(), fMasks, this->bitsPerPixel()));
msarett4ab9d5f2015-08-06 15:34:42 -070062
halcanary96fcdcc2015-08-27 07:41:13 -070063 if (nullptr == fMaskSwizzler.get()) {
msarett4ab9d5f2015-08-06 15:34:42 -070064 return false;
65 }
66
67 return true;
68}
69
msarett5406d6f2015-08-31 06:55:13 -070070SkCodec::Result SkBmpMaskCodec::prepareToDecode(const SkImageInfo& dstInfo,
71 const SkCodec::Options& options, SkPMColor inputColorPtr[], int* inputColorCount) {
72 // Initialize a the mask swizzler
73 if (!this->initializeSwizzler(dstInfo)) {
74 SkCodecPrintf("Error: cannot initialize swizzler.\n");
75 return SkCodec::kInvalidConversion;
76 }
77
78 return SkCodec::kSuccess;
79}
80
msarett4ab9d5f2015-08-06 15:34:42 -070081/*
82 * Performs the decoding
83 */
msarett5406d6f2015-08-31 06:55:13 -070084SkCodec::Result SkBmpMaskCodec::decodeRows(const SkImageInfo& dstInfo,
85 void* dst, size_t dstRowBytes,
86 const Options& opts) {
msarett4ab9d5f2015-08-06 15:34:42 -070087 // Iterate over rows of the image
88 uint8_t* srcRow = fSrcBuffer.get();
msarett5406d6f2015-08-31 06:55:13 -070089 const int height = dstInfo.height();
msarett4ab9d5f2015-08-06 15:34:42 -070090 for (int y = 0; y < height; y++) {
91 // Read a row of the input
msarett5406d6f2015-08-31 06:55:13 -070092 if (this->stream()->read(srcRow, fSrcRowBytes) != fSrcRowBytes) {
msarett4ab9d5f2015-08-06 15:34:42 -070093 SkCodecPrintf("Warning: incomplete input stream.\n");
94 // Fill the destination image on failure
msarett5406d6f2015-08-31 06:55:13 -070095 void* dstStart = this->getDstStartRow(dst, dstRowBytes, y);
96 uint32_t fillColor = get_fill_color_or_index(dstInfo.alphaType());
97 SkSwizzler::Fill(dstStart, dstInfo, dstRowBytes, height - y,
98 fillColor, nullptr, opts.fZeroInitialized);
msarett4ab9d5f2015-08-06 15:34:42 -070099 return kIncompleteInput;
100 }
101
102 // Decode the row in destination format
msarett5406d6f2015-08-31 06:55:13 -0700103 uint32_t row = this->getDstRow(y, height);
msarett4ab9d5f2015-08-06 15:34:42 -0700104 void* dstRow = SkTAddOffset<void>(dst, row * dstRowBytes);
105 fMaskSwizzler->swizzle(dstRow, srcRow);
106 }
107
108 // Finished decoding the entire image
109 return kSuccess;
110}