blob: a54734f431cff4c334b8a93dcd17779214d170c4 [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:
scroggodb30be22015-12-08 18:54:13 -080023 static bool IsBmp(const void*, size_t);
msarett74114382015-03-16 11:55:18 -070024
25 /*
msarett74114382015-03-16 11:55:18 -070026 * Assumes IsBmp was called and returned true
msarett9bde9182015-03-25 05:27:48 -070027 * Creates a bmp decoder
msarett74114382015-03-16 11:55:18 -070028 * Reads enough of the stream to determine the image format
msarett74114382015-03-16 11:55:18 -070029 */
30 static SkCodec* NewFromStream(SkStream*);
31
msarett9bde9182015-03-25 05:27:48 -070032 /*
msarett9bde9182015-03-25 05:27:48 -070033 * Creates a bmp decoder for a bmp embedded in ico
34 * Reads enough of the stream to determine the image format
msarett9bde9182015-03-25 05:27:48 -070035 */
36 static SkCodec* NewFromIco(SkStream*);
37
msarett74114382015-03-16 11:55:18 -070038protected:
39
msarett4ab9d5f2015-08-06 15:34:42 -070040 SkBmpCodec(const SkImageInfo& info, SkStream* stream, uint16_t bitsPerPixel,
scroggo46c57472015-09-30 08:57:13 -070041 SkCodec::SkScanlineOrder rowOrder);
msarett74114382015-03-16 11:55:18 -070042
mtklein36352bf2015-03-25 18:17:31 -070043 SkEncodedFormat onGetEncodedFormat() const override { return kBMP_SkEncodedFormat; }
msarett9bde9182015-03-25 05:27:48 -070044
msarett74114382015-03-16 11:55:18 -070045 /*
scroggo79e378d2015-04-01 07:39:40 -070046 * Read enough of the stream to initialize the SkBmpCodec. Returns a bool
47 * representing success or failure. If it returned true, and codecOut was
halcanary96fcdcc2015-08-27 07:41:13 -070048 * not nullptr, it will be set to a new SkBmpCodec.
scroggo0a7e69c2015-04-03 07:22:22 -070049 * Does *not* take ownership of the passed in SkStream.
scroggo79e378d2015-04-01 07:39:40 -070050 */
msarett4ab9d5f2015-08-06 15:34:42 -070051 static bool ReadHeader(SkStream*, bool inIco, SkCodec** codecOut);
scroggo79e378d2015-04-01 07:39:40 -070052
scroggob427db12015-08-12 07:24:13 -070053 bool onRewind() override;
54
scroggo79e378d2015-04-01 07:39:40 -070055 /*
scroggob427db12015-08-12 07:24:13 -070056 * Returns whether this BMP is part of an ICO image.
msarett74114382015-03-16 11:55:18 -070057 */
scroggob427db12015-08-12 07:24:13 -070058 bool inIco() const {
59 return this->onInIco();
60 }
61
62 virtual bool onInIco() const {
63 return false;
64 }
msarett74114382015-03-16 11:55:18 -070065
66 /*
msarett5406d6f2015-08-31 06:55:13 -070067 * 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 */
scroggo46c57472015-09-30 08:57:13 -070077 int32_t getDstRow(int32_t y, int32_t height) const;
msarett5406d6f2015-08-31 06:55:13 -070078
79 /*
msarett4ab9d5f2015-08-06 15:34:42 -070080 * Accessors used by subclasses
msarett74114382015-03-16 11:55:18 -070081 */
msarett4ab9d5f2015-08-06 15:34:42 -070082 uint16_t bitsPerPixel() const { return fBitsPerPixel; }
scroggo46c57472015-09-30 08:57:13 -070083 SkScanlineOrder onGetScanlineOrder() const override { return fRowOrder; }
msarett9b9497e2016-02-11 13:29:36 -080084 size_t srcRowBytes() const { return fSrcRowBytes; }
msarett5406d6f2015-08-31 06:55:13 -070085
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;
msarett4ab9d5f2015-08-06 15:34:42 -0700104
105private:
msarett74114382015-03-16 11:55:18 -0700106
107 /*
msarett4ab9d5f2015-08-06 15:34:42 -0700108 * Creates a bmp decoder
109 * Reads enough of the stream to determine the image format
msarett74114382015-03-16 11:55:18 -0700110 */
msarett4ab9d5f2015-08-06 15:34:42 -0700111 static SkCodec* NewFromStream(SkStream*, bool inIco);
msarett74114382015-03-16 11:55:18 -0700112
msarett5406d6f2015-08-31 06:55:13 -0700113 /*
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
msarette6dd0042015-10-09 11:07:34 -0700126 * @return Number of rows successfully decoded
msarett5406d6f2015-08-31 06:55:13 -0700127 */
msarette6dd0042015-10-09 11:07:34 -0700128 virtual int decodeRows(const SkImageInfo& dstInfo, void* dst, size_t dstRowBytes,
msarett5406d6f2015-08-31 06:55:13 -0700129 const Options& opts) = 0;
130
msarett9b9497e2016-02-11 13:29:36 -0800131 virtual bool skipRows(int count);
132
scroggo46c57472015-09-30 08:57:13 -0700133 Result onStartScanlineDecode(const SkImageInfo& dstInfo, const SkCodec::Options&,
134 SkPMColor inputColorPtr[], int* inputColorCount) override;
msarett5406d6f2015-08-31 06:55:13 -0700135
msarette6dd0042015-10-09 11:07:34 -0700136 int onGetScanlines(void* dst, int count, size_t rowBytes) override;
scroggo46c57472015-09-30 08:57:13 -0700137
msarett9b9497e2016-02-11 13:29:36 -0800138 bool onSkipScanlines(int count) override;
scroggo46c57472015-09-30 08:57:13 -0700139
140 const uint16_t fBitsPerPixel;
141 const SkScanlineOrder fRowOrder;
msarett9b9497e2016-02-11 13:29:36 -0800142 const size_t fSrcRowBytes;
msarett74114382015-03-16 11:55:18 -0700143
144 typedef SkCodec INHERITED;
145};
msarett4ab9d5f2015-08-06 15:34:42 -0700146
147#endif