blob: aec56ee2fa270eb4a4f684ce4a8592f69a5d0053 [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 */
Mike Reedede7bac2017-07-23 15:30:02 -040015SkBmpMaskCodec::SkBmpMaskCodec(int width, int height, const SkEncodedInfo& info,
16 std::unique_ptr<SkStream> stream,
msarett4ab9d5f2015-08-06 15:34:42 -070017 uint16_t bitsPerPixel, SkMasks* masks,
scroggo46c57472015-09-30 08:57:13 -070018 SkCodec::SkScanlineOrder rowOrder)
Mike Reedede7bac2017-07-23 15:30:02 -040019 : INHERITED(width, height, info, std::move(stream), bitsPerPixel, rowOrder)
msarett4ab9d5f2015-08-06 15:34:42 -070020 , fMasks(masks)
halcanary96fcdcc2015-08-27 07:41:13 -070021 , fMaskSwizzler(nullptr)
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,
msarette6dd0042015-10-09 11:07:34 -070030 int* rowsDecoded) {
msarett4ab9d5f2015-08-06 15:34:42 -070031 if (opts.fSubset) {
32 // Subsets are not supported.
33 return kUnimplemented;
34 }
35 if (dstInfo.dimensions() != this->getInfo().dimensions()) {
36 SkCodecPrintf("Error: scaling not supported.\n");
37 return kInvalidScale;
38 }
39
Leon Scroggins571b30f2017-07-11 17:35:31 +000040 Result result = this->prepareToDecode(dstInfo, opts);
msarett5406d6f2015-08-31 06:55:13 -070041 if (kSuccess != result) {
42 return result;
msarett4ab9d5f2015-08-06 15:34:42 -070043 }
44
msarettf724b992015-10-15 06:41:06 -070045 int rows = this->decodeRows(dstInfo, dst, dstRowBytes, opts);
msarette6dd0042015-10-09 11:07:34 -070046 if (rows != dstInfo.height()) {
47 *rowsDecoded = rows;
48 return kIncompleteInput;
49 }
50 return kSuccess;
msarett4ab9d5f2015-08-06 15:34:42 -070051}
52
Matt Sarett1b96c6f2016-11-03 16:15:20 -040053SkCodec::Result SkBmpMaskCodec::onPrepareToDecode(const SkImageInfo& dstInfo,
Leon Scroggins571b30f2017-07-11 17:35:31 +000054 const SkCodec::Options& options) {
Matt Sarett1b96c6f2016-11-03 16:15:20 -040055 if (this->colorXform()) {
56 this->resetXformBuffer(dstInfo.width());
57 }
58
59 SkImageInfo swizzlerInfo = dstInfo;
60 if (this->colorXform()) {
Matt Sarett562e6812016-11-08 16:13:43 -050061 swizzlerInfo = swizzlerInfo.makeColorType(kXformSrcColorType);
Matt Sarett1b96c6f2016-11-03 16:15:20 -040062 if (kPremul_SkAlphaType == dstInfo.alphaType()) {
63 swizzlerInfo = swizzlerInfo.makeAlphaType(kUnpremul_SkAlphaType);
64 }
65 }
66
msarettb30d6982016-02-15 10:18:45 -080067 // Initialize the mask swizzler
Matt Sarett1b96c6f2016-11-03 16:15:20 -040068 fMaskSwizzler.reset(SkMaskSwizzler::CreateMaskSwizzler(swizzlerInfo, this->getInfo(),
69 fMasks.get(), this->bitsPerPixel(), options));
msarettb30d6982016-02-15 10:18:45 -080070 SkASSERT(fMaskSwizzler);
msarett5406d6f2015-08-31 06:55:13 -070071
72 return SkCodec::kSuccess;
73}
74
msarett4ab9d5f2015-08-06 15:34:42 -070075/*
76 * Performs the decoding
77 */
msarette6dd0042015-10-09 11:07:34 -070078int SkBmpMaskCodec::decodeRows(const SkImageInfo& dstInfo,
msarett5406d6f2015-08-31 06:55:13 -070079 void* dst, size_t dstRowBytes,
80 const Options& opts) {
msarett4ab9d5f2015-08-06 15:34:42 -070081 // Iterate over rows of the image
Leon Scroggins IIId81fed92017-06-01 13:42:28 -040082 uint8_t* srcRow = this->srcBuffer();
msarett5406d6f2015-08-31 06:55:13 -070083 const int height = dstInfo.height();
msarett4ab9d5f2015-08-06 15:34:42 -070084 for (int y = 0; y < height; y++) {
85 // Read a row of the input
msarett9b9497e2016-02-11 13:29:36 -080086 if (this->stream()->read(srcRow, this->srcRowBytes()) != this->srcRowBytes()) {
msarett4ab9d5f2015-08-06 15:34:42 -070087 SkCodecPrintf("Warning: incomplete input stream.\n");
msarette6dd0042015-10-09 11:07:34 -070088 return y;
msarett4ab9d5f2015-08-06 15:34:42 -070089 }
90
91 // Decode the row in destination format
msarett5406d6f2015-08-31 06:55:13 -070092 uint32_t row = this->getDstRow(y, height);
msarett4ab9d5f2015-08-06 15:34:42 -070093 void* dstRow = SkTAddOffset<void>(dst, row * dstRowBytes);
Matt Sarett1b96c6f2016-11-03 16:15:20 -040094
95 if (this->colorXform()) {
Matt Sarett1b96c6f2016-11-03 16:15:20 -040096 fMaskSwizzler->swizzle(this->xformBuffer(), srcRow);
Leon Scroggins IIIc6e6a5f2017-06-05 15:53:38 -040097 this->applyColorXform(dstRow, this->xformBuffer(), fMaskSwizzler->swizzleWidth());
Matt Sarett1b96c6f2016-11-03 16:15:20 -040098 } else {
99 fMaskSwizzler->swizzle(dstRow, srcRow);
100 }
msarett4ab9d5f2015-08-06 15:34:42 -0700101 }
102
103 // Finished decoding the entire image
msarette6dd0042015-10-09 11:07:34 -0700104 return height;
msarett4ab9d5f2015-08-06 15:34:42 -0700105}