blob: ea6f789407cdab7ad15d5543bcdac516de8c5893 [file] [log] [blame]
msarett74114382015-03-16 11:55:18 -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 */
msarett4ab9d5f2015-08-06 15:34:42 -07007#ifndef SkBmpCodec_DEFINED
8#define SkBmpCodec_DEFINED
msarett74114382015-03-16 11:55:18 -07009
10#include "SkCodec.h"
msaretteed039b2015-03-18 11:11:19 -070011#include "SkColorTable.h"
msarett74114382015-03-16 11:55:18 -070012#include "SkImageInfo.h"
13#include "SkMaskSwizzler.h"
14#include "SkStream.h"
15#include "SkSwizzler.h"
16#include "SkTypes.h"
17
msarett74114382015-03-16 11:55:18 -070018/*
msarett4ab9d5f2015-08-06 15:34:42 -070019 * This class enables code sharing between its bmp codec subclasses. The
20 * subclasses actually do the work.
msarett74114382015-03-16 11:55:18 -070021 */
22class SkBmpCodec : public SkCodec {
23public:
24
25 /*
msarett9bde9182015-03-25 05:27:48 -070026 * Checks the start of the stream to see if the image is a bmp
msarett74114382015-03-16 11:55:18 -070027 */
28 static bool IsBmp(SkStream*);
29
30 /*
msarett74114382015-03-16 11:55:18 -070031 * Assumes IsBmp was called and returned true
msarett9bde9182015-03-25 05:27:48 -070032 * Creates a bmp decoder
msarett74114382015-03-16 11:55:18 -070033 * Reads enough of the stream to determine the image format
msarett74114382015-03-16 11:55:18 -070034 */
35 static SkCodec* NewFromStream(SkStream*);
36
msarett9bde9182015-03-25 05:27:48 -070037 /*
msarett9bde9182015-03-25 05:27:48 -070038 * Creates a bmp decoder for a bmp embedded in ico
39 * Reads enough of the stream to determine the image format
msarett9bde9182015-03-25 05:27:48 -070040 */
41 static SkCodec* NewFromIco(SkStream*);
42
msarett74114382015-03-16 11:55:18 -070043protected:
44
msarett4ab9d5f2015-08-06 15:34:42 -070045 SkBmpCodec(const SkImageInfo& info, SkStream* stream, uint16_t bitsPerPixel,
scroggo46c57472015-09-30 08:57:13 -070046 SkCodec::SkScanlineOrder rowOrder);
msarett74114382015-03-16 11:55:18 -070047
mtklein36352bf2015-03-25 18:17:31 -070048 SkEncodedFormat onGetEncodedFormat() const override { return kBMP_SkEncodedFormat; }
msarett9bde9182015-03-25 05:27:48 -070049
msarett74114382015-03-16 11:55:18 -070050 /*
scroggo79e378d2015-04-01 07:39:40 -070051 * Read enough of the stream to initialize the SkBmpCodec. Returns a bool
52 * representing success or failure. If it returned true, and codecOut was
halcanary96fcdcc2015-08-27 07:41:13 -070053 * not nullptr, it will be set to a new SkBmpCodec.
scroggo0a7e69c2015-04-03 07:22:22 -070054 * Does *not* take ownership of the passed in SkStream.
scroggo79e378d2015-04-01 07:39:40 -070055 */
msarett4ab9d5f2015-08-06 15:34:42 -070056 static bool ReadHeader(SkStream*, bool inIco, SkCodec** codecOut);
scroggo79e378d2015-04-01 07:39:40 -070057
scroggob427db12015-08-12 07:24:13 -070058 bool onRewind() override;
59
scroggo79e378d2015-04-01 07:39:40 -070060 /*
scroggob427db12015-08-12 07:24:13 -070061 * Returns whether this BMP is part of an ICO image.
msarett74114382015-03-16 11:55:18 -070062 */
scroggob427db12015-08-12 07:24:13 -070063 bool inIco() const {
64 return this->onInIco();
65 }
66
67 virtual bool onInIco() const {
68 return false;
69 }
msarett74114382015-03-16 11:55:18 -070070
71 /*
msarett5406d6f2015-08-31 06:55:13 -070072 * Get the destination row number corresponding to the encoded row number.
73 * For kTopDown, we simply return y, but for kBottomUp, the rows will be
74 * decoded in reverse order.
75 *
76 * @param y Iterates from 0 to height, indicating the current row.
77 * @param height The height of the current subset of the image that we are
78 * decoding. This is generally equal to the full height
79 * when we want to decode the full or one when we are
80 * sampling.
81 */
scroggo46c57472015-09-30 08:57:13 -070082 int32_t getDstRow(int32_t y, int32_t height) const;
msarett5406d6f2015-08-31 06:55:13 -070083
84 /*
msarett4ab9d5f2015-08-06 15:34:42 -070085 * Get the destination row to start filling from
86 * Used to fill the remainder of the image on incomplete input for bmps
87 * This is tricky since bmps may be kTopDown or kBottomUp. For kTopDown,
88 * we start filling from where we left off, but for kBottomUp we start
89 * filling at the top of the image.
msarett74114382015-03-16 11:55:18 -070090 */
msarett4ab9d5f2015-08-06 15:34:42 -070091 void* getDstStartRow(void* dst, size_t dstRowBytes, int32_t y) const;
msarett74114382015-03-16 11:55:18 -070092
93 /*
msarett4ab9d5f2015-08-06 15:34:42 -070094 * Compute the number of colors in the color table
msarett74114382015-03-16 11:55:18 -070095 */
msarett4ab9d5f2015-08-06 15:34:42 -070096 uint32_t computeNumColors(uint32_t numColors);
msarett74114382015-03-16 11:55:18 -070097
98 /*
msarett4ab9d5f2015-08-06 15:34:42 -070099 * Accessors used by subclasses
msarett74114382015-03-16 11:55:18 -0700100 */
msarett4ab9d5f2015-08-06 15:34:42 -0700101 uint16_t bitsPerPixel() const { return fBitsPerPixel; }
scroggo46c57472015-09-30 08:57:13 -0700102 SkScanlineOrder onGetScanlineOrder() const override { return fRowOrder; }
msarett5406d6f2015-08-31 06:55:13 -0700103
104 /*
105 * To be overriden by bmp subclasses, which provide unique implementations.
106 * Performs subclass specific setup.
107 *
108 * @param dstInfo Contains output information. Height specifies
109 * the total number of rows that will be decoded.
110 * @param options Additonal options to pass to the decoder.
111 * @param inputColorPtr Client-provided memory for a color table. Must
112 * be enough for 256 colors. This will be
113 * populated with colors if the encoded image uses
114 * a color table.
115 * @param inputColorCount If the encoded image uses a color table, this
116 * will be set to the number of colors in the
117 * color table.
118 */
119 virtual SkCodec::Result prepareToDecode(const SkImageInfo& dstInfo,
120 const SkCodec::Options& options, SkPMColor inputColorPtr[],
121 int* inputColorCount) = 0;
msarett4ab9d5f2015-08-06 15:34:42 -0700122
123private:
msarett74114382015-03-16 11:55:18 -0700124
125 /*
msarett4ab9d5f2015-08-06 15:34:42 -0700126 * Creates a bmp decoder
127 * Reads enough of the stream to determine the image format
msarett74114382015-03-16 11:55:18 -0700128 */
msarett4ab9d5f2015-08-06 15:34:42 -0700129 static SkCodec* NewFromStream(SkStream*, bool inIco);
msarett74114382015-03-16 11:55:18 -0700130
msarett5406d6f2015-08-31 06:55:13 -0700131 /*
132 * Decodes the next dstInfo.height() lines.
133 *
134 * onGetPixels() uses this for full image decodes.
135 * SkScaledCodec::onGetPixels() uses the scanline decoder to call this with
136 * dstInfo.height() = 1, in order to implement sampling.
137 * A potential future use is to allow the caller to decode a subset of the
138 * lines in the image.
139 *
140 * @param dstInfo Contains output information. Height specifies the
141 * number of rows to decode at this time.
142 * @param dst Memory location to store output pixels
143 * @param dstRowBytes Bytes in a row of the destination
144 */
145 virtual Result decodeRows(const SkImageInfo& dstInfo, void* dst, size_t dstRowBytes,
146 const Options& opts) = 0;
147
scroggo46c57472015-09-30 08:57:13 -0700148 Result onStartScanlineDecode(const SkImageInfo& dstInfo, const SkCodec::Options&,
149 SkPMColor inputColorPtr[], int* inputColorCount) override;
msarett5406d6f2015-08-31 06:55:13 -0700150
scroggo46c57472015-09-30 08:57:13 -0700151 Result onGetScanlines(void* dst, int count, size_t rowBytes) override;
152
153 int onNextScanline() const override;
154
155 // TODO(msarett): Override default skipping with something more clever.
156
157 const uint16_t fBitsPerPixel;
158 const SkScanlineOrder fRowOrder;
msarett74114382015-03-16 11:55:18 -0700159
160 typedef SkCodec INHERITED;
161};
msarett4ab9d5f2015-08-06 15:34:42 -0700162
163#endif