blob: 51060e5e9971ee78efe9f92c70557c27d394216a [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)
msarett4ab9d5f2015-08-06 15:34:42 -070021{}
22
23/*
24 * Initiates the bitmap decode
25 */
26SkCodec::Result SkBmpMaskCodec::onGetPixels(const SkImageInfo& dstInfo,
27 void* dst, size_t dstRowBytes,
28 const Options& opts,
msarette6dd0042015-10-09 11:07:34 -070029 int* rowsDecoded) {
msarett4ab9d5f2015-08-06 15:34:42 -070030 if (opts.fSubset) {
31 // Subsets are not supported.
32 return kUnimplemented;
33 }
34 if (dstInfo.dimensions() != this->getInfo().dimensions()) {
35 SkCodecPrintf("Error: scaling not supported.\n");
36 return kInvalidScale;
37 }
38
Leon Scroggins571b30f2017-07-11 17:35:31 +000039 Result result = this->prepareToDecode(dstInfo, opts);
msarett5406d6f2015-08-31 06:55:13 -070040 if (kSuccess != result) {
41 return result;
msarett4ab9d5f2015-08-06 15:34:42 -070042 }
43
msarettf724b992015-10-15 06:41:06 -070044 int rows = this->decodeRows(dstInfo, dst, dstRowBytes, opts);
msarette6dd0042015-10-09 11:07:34 -070045 if (rows != dstInfo.height()) {
46 *rowsDecoded = rows;
47 return kIncompleteInput;
48 }
49 return kSuccess;
msarett4ab9d5f2015-08-06 15:34:42 -070050}
51
Matt Sarett1b96c6f2016-11-03 16:15:20 -040052SkCodec::Result SkBmpMaskCodec::onPrepareToDecode(const SkImageInfo& dstInfo,
Leon Scroggins571b30f2017-07-11 17:35:31 +000053 const SkCodec::Options& options) {
Matt Sarett1b96c6f2016-11-03 16:15:20 -040054 if (this->colorXform()) {
55 this->resetXformBuffer(dstInfo.width());
56 }
57
58 SkImageInfo swizzlerInfo = dstInfo;
59 if (this->colorXform()) {
Matt Sarett562e6812016-11-08 16:13:43 -050060 swizzlerInfo = swizzlerInfo.makeColorType(kXformSrcColorType);
Matt Sarett1b96c6f2016-11-03 16:15:20 -040061 if (kPremul_SkAlphaType == dstInfo.alphaType()) {
62 swizzlerInfo = swizzlerInfo.makeAlphaType(kUnpremul_SkAlphaType);
63 }
64 }
65
msarettb30d6982016-02-15 10:18:45 -080066 // Initialize the mask swizzler
Matt Sarett1b96c6f2016-11-03 16:15:20 -040067 fMaskSwizzler.reset(SkMaskSwizzler::CreateMaskSwizzler(swizzlerInfo, this->getInfo(),
68 fMasks.get(), this->bitsPerPixel(), options));
msarettb30d6982016-02-15 10:18:45 -080069 SkASSERT(fMaskSwizzler);
msarett5406d6f2015-08-31 06:55:13 -070070
71 return SkCodec::kSuccess;
72}
73
msarett4ab9d5f2015-08-06 15:34:42 -070074/*
75 * Performs the decoding
76 */
msarette6dd0042015-10-09 11:07:34 -070077int SkBmpMaskCodec::decodeRows(const SkImageInfo& dstInfo,
msarett5406d6f2015-08-31 06:55:13 -070078 void* dst, size_t dstRowBytes,
79 const Options& opts) {
msarett4ab9d5f2015-08-06 15:34:42 -070080 // Iterate over rows of the image
Leon Scroggins IIId81fed92017-06-01 13:42:28 -040081 uint8_t* srcRow = this->srcBuffer();
msarett5406d6f2015-08-31 06:55:13 -070082 const int height = dstInfo.height();
msarett4ab9d5f2015-08-06 15:34:42 -070083 for (int y = 0; y < height; y++) {
84 // Read a row of the input
msarett9b9497e2016-02-11 13:29:36 -080085 if (this->stream()->read(srcRow, this->srcRowBytes()) != this->srcRowBytes()) {
msarett4ab9d5f2015-08-06 15:34:42 -070086 SkCodecPrintf("Warning: incomplete input stream.\n");
msarette6dd0042015-10-09 11:07:34 -070087 return y;
msarett4ab9d5f2015-08-06 15:34:42 -070088 }
89
90 // Decode the row in destination format
msarett5406d6f2015-08-31 06:55:13 -070091 uint32_t row = this->getDstRow(y, height);
msarett4ab9d5f2015-08-06 15:34:42 -070092 void* dstRow = SkTAddOffset<void>(dst, row * dstRowBytes);
Matt Sarett1b96c6f2016-11-03 16:15:20 -040093
94 if (this->colorXform()) {
Matt Sarett1b96c6f2016-11-03 16:15:20 -040095 fMaskSwizzler->swizzle(this->xformBuffer(), srcRow);
Leon Scroggins IIIc6e6a5f2017-06-05 15:53:38 -040096 this->applyColorXform(dstRow, this->xformBuffer(), fMaskSwizzler->swizzleWidth());
Matt Sarett1b96c6f2016-11-03 16:15:20 -040097 } else {
98 fMaskSwizzler->swizzle(dstRow, srcRow);
99 }
msarett4ab9d5f2015-08-06 15:34:42 -0700100 }
101
102 // Finished decoding the entire image
msarette6dd0042015-10-09 11:07:34 -0700103 return height;
msarett4ab9d5f2015-08-06 15:34:42 -0700104}