blob: 65662ff1f869df3a655799f93e73598ed57a4a6a [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"
msarett74114382015-03-16 11:55:18 -070013#include "SkStream.h"
14#include "SkSwizzler.h"
15#include "SkTypes.h"
16
msarett74114382015-03-16 11:55:18 -070017/*
msarett4ab9d5f2015-08-06 15:34:42 -070018 * This class enables code sharing between its bmp codec subclasses. The
19 * subclasses actually do the work.
msarett74114382015-03-16 11:55:18 -070020 */
21class SkBmpCodec : public SkCodec {
22public:
23
24 /*
msarett9bde9182015-03-25 05:27:48 -070025 * Checks the start of the stream to see if the image is a bmp
msarett74114382015-03-16 11:55:18 -070026 */
27 static bool IsBmp(SkStream*);
28
29 /*
msarett74114382015-03-16 11:55:18 -070030 * Assumes IsBmp was called and returned true
msarett9bde9182015-03-25 05:27:48 -070031 * Creates a bmp decoder
msarett74114382015-03-16 11:55:18 -070032 * Reads enough of the stream to determine the image format
msarett74114382015-03-16 11:55:18 -070033 */
34 static SkCodec* NewFromStream(SkStream*);
35
msarett9bde9182015-03-25 05:27:48 -070036 /*
msarett9bde9182015-03-25 05:27:48 -070037 * Creates a bmp decoder for a bmp embedded in ico
38 * Reads enough of the stream to determine the image format
msarett9bde9182015-03-25 05:27:48 -070039 */
40 static SkCodec* NewFromIco(SkStream*);
41
msarett74114382015-03-16 11:55:18 -070042protected:
43
msarett4ab9d5f2015-08-06 15:34:42 -070044 SkBmpCodec(const SkImageInfo& info, SkStream* stream, uint16_t bitsPerPixel,
scroggo46c57472015-09-30 08:57:13 -070045 SkCodec::SkScanlineOrder rowOrder);
msarett74114382015-03-16 11:55:18 -070046
mtklein36352bf2015-03-25 18:17:31 -070047 SkEncodedFormat onGetEncodedFormat() const override { return kBMP_SkEncodedFormat; }
msarett9bde9182015-03-25 05:27:48 -070048
msarett74114382015-03-16 11:55:18 -070049 /*
scroggo79e378d2015-04-01 07:39:40 -070050 * Read enough of the stream to initialize the SkBmpCodec. Returns a bool
51 * representing success or failure. If it returned true, and codecOut was
halcanary96fcdcc2015-08-27 07:41:13 -070052 * not nullptr, it will be set to a new SkBmpCodec.
scroggo0a7e69c2015-04-03 07:22:22 -070053 * Does *not* take ownership of the passed in SkStream.
scroggo79e378d2015-04-01 07:39:40 -070054 */
msarett4ab9d5f2015-08-06 15:34:42 -070055 static bool ReadHeader(SkStream*, bool inIco, SkCodec** codecOut);
scroggo79e378d2015-04-01 07:39:40 -070056
scroggob427db12015-08-12 07:24:13 -070057 bool onRewind() override;
58
scroggo79e378d2015-04-01 07:39:40 -070059 /*
scroggob427db12015-08-12 07:24:13 -070060 * Returns whether this BMP is part of an ICO image.
msarett74114382015-03-16 11:55:18 -070061 */
scroggob427db12015-08-12 07:24:13 -070062 bool inIco() const {
63 return this->onInIco();
64 }
65
66 virtual bool onInIco() const {
67 return false;
68 }
msarett74114382015-03-16 11:55:18 -070069
70 /*
msarett5406d6f2015-08-31 06:55:13 -070071 * Get the destination row number corresponding to the encoded row number.
72 * For kTopDown, we simply return y, but for kBottomUp, the rows will be
73 * decoded in reverse order.
74 *
75 * @param y Iterates from 0 to height, indicating the current row.
76 * @param height The height of the current subset of the image that we are
77 * decoding. This is generally equal to the full height
78 * when we want to decode the full or one when we are
79 * sampling.
80 */
scroggo46c57472015-09-30 08:57:13 -070081 int32_t getDstRow(int32_t y, int32_t height) const;
msarett5406d6f2015-08-31 06:55:13 -070082
83 /*
msarett4ab9d5f2015-08-06 15:34:42 -070084 * Compute the number of colors in the color table
msarett74114382015-03-16 11:55:18 -070085 */
msarett4ab9d5f2015-08-06 15:34:42 -070086 uint32_t computeNumColors(uint32_t numColors);
msarett74114382015-03-16 11:55:18 -070087
88 /*
msarett4ab9d5f2015-08-06 15:34:42 -070089 * Accessors used by subclasses
msarett74114382015-03-16 11:55:18 -070090 */
msarett4ab9d5f2015-08-06 15:34:42 -070091 uint16_t bitsPerPixel() const { return fBitsPerPixel; }
scroggo46c57472015-09-30 08:57:13 -070092 SkScanlineOrder onGetScanlineOrder() const override { return fRowOrder; }
msarett5406d6f2015-08-31 06:55:13 -070093
94 /*
95 * To be overriden by bmp subclasses, which provide unique implementations.
96 * Performs subclass specific setup.
97 *
98 * @param dstInfo Contains output information. Height specifies
99 * the total number of rows that will be decoded.
100 * @param options Additonal options to pass to the decoder.
101 * @param inputColorPtr Client-provided memory for a color table. Must
102 * be enough for 256 colors. This will be
103 * populated with colors if the encoded image uses
104 * a color table.
105 * @param inputColorCount If the encoded image uses a color table, this
106 * will be set to the number of colors in the
107 * color table.
108 */
109 virtual SkCodec::Result prepareToDecode(const SkImageInfo& dstInfo,
110 const SkCodec::Options& options, SkPMColor inputColorPtr[],
111 int* inputColorCount) = 0;
msarett4ab9d5f2015-08-06 15:34:42 -0700112
113private:
msarett74114382015-03-16 11:55:18 -0700114
115 /*
msarett4ab9d5f2015-08-06 15:34:42 -0700116 * Creates a bmp decoder
117 * Reads enough of the stream to determine the image format
msarett74114382015-03-16 11:55:18 -0700118 */
msarett4ab9d5f2015-08-06 15:34:42 -0700119 static SkCodec* NewFromStream(SkStream*, bool inIco);
msarett74114382015-03-16 11:55:18 -0700120
msarett5406d6f2015-08-31 06:55:13 -0700121 /*
122 * Decodes the next dstInfo.height() lines.
123 *
124 * onGetPixels() uses this for full image decodes.
125 * SkScaledCodec::onGetPixels() uses the scanline decoder to call this with
126 * dstInfo.height() = 1, in order to implement sampling.
127 * A potential future use is to allow the caller to decode a subset of the
128 * lines in the image.
129 *
130 * @param dstInfo Contains output information. Height specifies the
131 * number of rows to decode at this time.
132 * @param dst Memory location to store output pixels
133 * @param dstRowBytes Bytes in a row of the destination
msarette6dd0042015-10-09 11:07:34 -0700134 * @return Number of rows successfully decoded
msarett5406d6f2015-08-31 06:55:13 -0700135 */
msarette6dd0042015-10-09 11:07:34 -0700136 virtual int decodeRows(const SkImageInfo& dstInfo, void* dst, size_t dstRowBytes,
msarett5406d6f2015-08-31 06:55:13 -0700137 const Options& opts) = 0;
138
scroggo46c57472015-09-30 08:57:13 -0700139 Result onStartScanlineDecode(const SkImageInfo& dstInfo, const SkCodec::Options&,
140 SkPMColor inputColorPtr[], int* inputColorCount) override;
msarett5406d6f2015-08-31 06:55:13 -0700141
msarette6dd0042015-10-09 11:07:34 -0700142 int onGetScanlines(void* dst, int count, size_t rowBytes) override;
scroggo46c57472015-09-30 08:57:13 -0700143
144 // TODO(msarett): Override default skipping with something more clever.
145
146 const uint16_t fBitsPerPixel;
147 const SkScanlineOrder fRowOrder;
msarett74114382015-03-16 11:55:18 -0700148
149 typedef SkCodec INHERITED;
150};
msarett4ab9d5f2015-08-06 15:34:42 -0700151
152#endif