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#ifndef SkBmpCodec_DEFINED 8#define SkBmpCodec_DEFINED 9 10#include "SkCodec.h" 11#include "SkColorTable.h" 12#include "SkImageInfo.h" 13#include "SkStream.h" 14#include "SkSwizzler.h" 15#include "SkTypes.h" 16 17/* 18 * This class enables code sharing between its bmp codec subclasses. The 19 * subclasses actually do the work. 20 */ 21class SkBmpCodec : public SkCodec { 22public: 23 static bool IsBmp(const void*, size_t); 24 25 /* 26 * Assumes IsBmp was called and returned true 27 * Creates a bmp decoder 28 * Reads enough of the stream to determine the image format 29 */ 30 static SkCodec* NewFromStream(SkStream*); 31 32 /* 33 * Creates a bmp decoder for a bmp embedded in ico 34 * Reads enough of the stream to determine the image format 35 */ 36 static SkCodec* NewFromIco(SkStream*); 37 38protected: 39 40 SkBmpCodec(const SkImageInfo& info, SkStream* stream, uint16_t bitsPerPixel, 41 SkCodec::SkScanlineOrder rowOrder); 42 43 SkEncodedFormat onGetEncodedFormat() const override { return kBMP_SkEncodedFormat; } 44 45 /* 46 * Read enough of the stream to initialize the SkBmpCodec. Returns a bool 47 * representing success or failure. If it returned true, and codecOut was 48 * not nullptr, it will be set to a new SkBmpCodec. 49 * Does *not* take ownership of the passed in SkStream. 50 */ 51 static bool ReadHeader(SkStream*, bool inIco, SkCodec** codecOut); 52 53 bool onRewind() override; 54 55 /* 56 * Returns whether this BMP is part of an ICO image. 57 */ 58 bool inIco() const { 59 return this->onInIco(); 60 } 61 62 virtual bool onInIco() const { 63 return false; 64 } 65 66 /* 67 * Get the destination row number corresponding to the encoded row number. 68 * For kTopDown, we simply return y, but for kBottomUp, the rows will be 69 * decoded in reverse order. 70 * 71 * @param y Iterates from 0 to height, indicating the current row. 72 * @param height The height of the current subset of the image that we are 73 * decoding. This is generally equal to the full height 74 * when we want to decode the full or one when we are 75 * sampling. 76 */ 77 int32_t getDstRow(int32_t y, int32_t height) const; 78 79 /* 80 * Accessors used by subclasses 81 */ 82 uint16_t bitsPerPixel() const { return fBitsPerPixel; } 83 SkScanlineOrder onGetScanlineOrder() const override { return fRowOrder; } 84 size_t srcRowBytes() const { return fSrcRowBytes; } 85 86 /* 87 * To be overriden by bmp subclasses, which provide unique implementations. 88 * Performs subclass specific setup. 89 * 90 * @param dstInfo Contains output information. Height specifies 91 * the total number of rows that will be decoded. 92 * @param options Additonal options to pass to the decoder. 93 * @param inputColorPtr Client-provided memory for a color table. Must 94 * be enough for 256 colors. This will be 95 * populated with colors if the encoded image uses 96 * a color table. 97 * @param inputColorCount If the encoded image uses a color table, this 98 * will be set to the number of colors in the 99 * color table. 100 */ 101 virtual SkCodec::Result prepareToDecode(const SkImageInfo& dstInfo, 102 const SkCodec::Options& options, SkPMColor inputColorPtr[], 103 int* inputColorCount) = 0; 104 105private: 106 107 /* 108 * Creates a bmp decoder 109 * Reads enough of the stream to determine the image format 110 */ 111 static SkCodec* NewFromStream(SkStream*, bool inIco); 112 113 /* 114 * Decodes the next dstInfo.height() lines. 115 * 116 * onGetPixels() uses this for full image decodes. 117 * SkScaledCodec::onGetPixels() uses the scanline decoder to call this with 118 * dstInfo.height() = 1, in order to implement sampling. 119 * A potential future use is to allow the caller to decode a subset of the 120 * lines in the image. 121 * 122 * @param dstInfo Contains output information. Height specifies the 123 * number of rows to decode at this time. 124 * @param dst Memory location to store output pixels 125 * @param dstRowBytes Bytes in a row of the destination 126 * @return Number of rows successfully decoded 127 */ 128 virtual int decodeRows(const SkImageInfo& dstInfo, void* dst, size_t dstRowBytes, 129 const Options& opts) = 0; 130 131 virtual bool skipRows(int count); 132 133 Result onStartScanlineDecode(const SkImageInfo& dstInfo, const SkCodec::Options&, 134 SkPMColor inputColorPtr[], int* inputColorCount) override; 135 136 int onGetScanlines(void* dst, int count, size_t rowBytes) override; 137 138 bool onSkipScanlines(int count) override; 139 140 const uint16_t fBitsPerPixel; 141 const SkScanlineOrder fRowOrder; 142 const size_t fSrcRowBytes; 143 144 typedef SkCodec INHERITED; 145}; 146 147#endif 148