1 /* 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 "SkColorData.h" 11 12 /* 13 * Creates an instance of the decoder 14 */ 15 SkBmpMaskCodec::SkBmpMaskCodec(SkEncodedInfo&& info, 16 std::unique_ptr<SkStream> stream, 17 uint16_t bitsPerPixel, SkMasks* masks, 18 SkCodec::SkScanlineOrder rowOrder) 19 : INHERITED(std::move(info), std::move(stream), bitsPerPixel, rowOrder) 20 , fMasks(masks) 21 , fMaskSwizzler(nullptr) 22 {} 23 24 /* 25 * Initiates the bitmap decode 26 */ 27 SkCodec::Result SkBmpMaskCodec::onGetPixels(const SkImageInfo& dstInfo, 28 void* dst, size_t dstRowBytes, 29 const Options& opts, 30 int* rowsDecoded) { 31 if (opts.fSubset) { 32 // Subsets are not supported. 33 return kUnimplemented; 34 } 35 if (dstInfo.dimensions() != this->dimensions()) { 36 SkCodecPrintf("Error: scaling not supported.\n"); 37 return kInvalidScale; 38 } 39 40 Result result = this->prepareToDecode(dstInfo, opts); 41 if (kSuccess != result) { 42 return result; 43 } 44 45 int rows = this->decodeRows(dstInfo, dst, dstRowBytes, opts); 46 if (rows != dstInfo.height()) { 47 *rowsDecoded = rows; 48 return kIncompleteInput; 49 } 50 return kSuccess; 51 } 52 53 SkCodec::Result SkBmpMaskCodec::onPrepareToDecode(const SkImageInfo& dstInfo, 54 const SkCodec::Options& options) { 55 if (this->colorXform()) { 56 this->resetXformBuffer(dstInfo.width()); 57 } 58 59 SkImageInfo swizzlerInfo = dstInfo; 60 if (this->colorXform()) { 61 swizzlerInfo = swizzlerInfo.makeColorType(kXformSrcColorType); 62 if (kPremul_SkAlphaType == dstInfo.alphaType()) { 63 swizzlerInfo = swizzlerInfo.makeAlphaType(kUnpremul_SkAlphaType); 64 } 65 } 66 67 bool srcIsOpaque = this->getEncodedInfo().opaque(); 68 fMaskSwizzler.reset(SkMaskSwizzler::CreateMaskSwizzler(swizzlerInfo, srcIsOpaque, 69 fMasks.get(), this->bitsPerPixel(), options)); 70 SkASSERT(fMaskSwizzler); 71 72 return SkCodec::kSuccess; 73 } 74 75 /* 76 * Performs the decoding 77 */ 78 int SkBmpMaskCodec::decodeRows(const SkImageInfo& dstInfo, 79 void* dst, size_t dstRowBytes, 80 const Options& opts) { 81 // Iterate over rows of the image 82 uint8_t* srcRow = this->srcBuffer(); 83 const int height = dstInfo.height(); 84 for (int y = 0; y < height; y++) { 85 // Read a row of the input 86 if (this->stream()->read(srcRow, this->srcRowBytes()) != this->srcRowBytes()) { 87 SkCodecPrintf("Warning: incomplete input stream.\n"); 88 return y; 89 } 90 91 // Decode the row in destination format 92 uint32_t row = this->getDstRow(y, height); 93 void* dstRow = SkTAddOffset<void>(dst, row * dstRowBytes); 94 95 if (this->colorXform()) { 96 fMaskSwizzler->swizzle(this->xformBuffer(), srcRow); 97 this->applyColorXform(dstRow, this->xformBuffer(), fMaskSwizzler->swizzleWidth()); 98 } else { 99 fMaskSwizzler->swizzle(dstRow, srcRow); 100 } 101 } 102 103 // Finished decoding the entire image 104 return height; 105 } 106