blob: 7d2d398bb475ebc4dcb57e1aecb1b0e9c46a0721 [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 */
msarettc30c4182016-04-20 11:53:35 -070015SkBmpMaskCodec::SkBmpMaskCodec(int width, int height, const SkEncodedInfo& info, SkStream* stream,
msarett4ab9d5f2015-08-06 15:34:42 -070016 uint16_t bitsPerPixel, SkMasks* masks,
scroggo46c57472015-09-30 08:57:13 -070017 SkCodec::SkScanlineOrder rowOrder)
msarettc30c4182016-04-20 11:53:35 -070018 : INHERITED(width, height, info, stream, bitsPerPixel, rowOrder)
msarett4ab9d5f2015-08-06 15:34:42 -070019 , fMasks(masks)
halcanary96fcdcc2015-08-27 07:41:13 -070020 , fMaskSwizzler(nullptr)
msarett9b9497e2016-02-11 13:29:36 -080021 , fSrcBuffer(new uint8_t [this->srcRowBytes()])
msarett4ab9d5f2015-08-06 15:34:42 -070022{}
23
24/*
25 * Initiates the bitmap decode
26 */
27SkCodec::Result SkBmpMaskCodec::onGetPixels(const SkImageInfo& dstInfo,
28 void* dst, size_t dstRowBytes,
29 const Options& opts,
30 SkPMColor* inputColorPtr,
msarette6dd0042015-10-09 11:07:34 -070031 int* inputColorCount,
32 int* rowsDecoded) {
msarett4ab9d5f2015-08-06 15:34:42 -070033 if (opts.fSubset) {
34 // Subsets are not supported.
35 return kUnimplemented;
36 }
37 if (dstInfo.dimensions() != this->getInfo().dimensions()) {
38 SkCodecPrintf("Error: scaling not supported.\n");
39 return kInvalidScale;
40 }
41
42 if (!conversion_possible(dstInfo, this->getInfo())) {
43 SkCodecPrintf("Error: cannot convert input type to output type.\n");
44 return kInvalidConversion;
45 }
46
msarett5406d6f2015-08-31 06:55:13 -070047 Result result = this->prepareToDecode(dstInfo, opts, inputColorPtr, inputColorCount);
48 if (kSuccess != result) {
49 return result;
msarett4ab9d5f2015-08-06 15:34:42 -070050 }
51
msarettf724b992015-10-15 06:41:06 -070052 int rows = this->decodeRows(dstInfo, dst, dstRowBytes, opts);
msarette6dd0042015-10-09 11:07:34 -070053 if (rows != dstInfo.height()) {
54 *rowsDecoded = rows;
55 return kIncompleteInput;
56 }
57 return kSuccess;
msarett4ab9d5f2015-08-06 15:34:42 -070058}
59
msarettdeabdb52016-02-12 15:00:10 -080060SkCodec::Result SkBmpMaskCodec::prepareToDecode(const SkImageInfo& dstInfo,
61 const SkCodec::Options& options, SkPMColor inputColorPtr[], int* inputColorCount) {
msarettb30d6982016-02-15 10:18:45 -080062 // Initialize the mask swizzler
63 fMaskSwizzler.reset(SkMaskSwizzler::CreateMaskSwizzler(dstInfo, this->getInfo(), fMasks,
64 this->bitsPerPixel(), options));
65 SkASSERT(fMaskSwizzler);
msarett5406d6f2015-08-31 06:55:13 -070066
67 return SkCodec::kSuccess;
68}
69
msarett4ab9d5f2015-08-06 15:34:42 -070070/*
71 * Performs the decoding
72 */
msarette6dd0042015-10-09 11:07:34 -070073int SkBmpMaskCodec::decodeRows(const SkImageInfo& dstInfo,
msarett5406d6f2015-08-31 06:55:13 -070074 void* dst, size_t dstRowBytes,
75 const Options& opts) {
msarett4ab9d5f2015-08-06 15:34:42 -070076 // Iterate over rows of the image
77 uint8_t* srcRow = fSrcBuffer.get();
msarett5406d6f2015-08-31 06:55:13 -070078 const int height = dstInfo.height();
msarett4ab9d5f2015-08-06 15:34:42 -070079 for (int y = 0; y < height; y++) {
80 // Read a row of the input
msarett9b9497e2016-02-11 13:29:36 -080081 if (this->stream()->read(srcRow, this->srcRowBytes()) != this->srcRowBytes()) {
msarett4ab9d5f2015-08-06 15:34:42 -070082 SkCodecPrintf("Warning: incomplete input stream.\n");
msarette6dd0042015-10-09 11:07:34 -070083 return y;
msarett4ab9d5f2015-08-06 15:34:42 -070084 }
85
86 // Decode the row in destination format
msarett5406d6f2015-08-31 06:55:13 -070087 uint32_t row = this->getDstRow(y, height);
msarett4ab9d5f2015-08-06 15:34:42 -070088 void* dstRow = SkTAddOffset<void>(dst, row * dstRowBytes);
89 fMaskSwizzler->swizzle(dstRow, srcRow);
90 }
91
92 // Finished decoding the entire image
msarette6dd0042015-10-09 11:07:34 -070093 return height;
msarett4ab9d5f2015-08-06 15:34:42 -070094}