blob: 0ece7ad6ce2fb1b5bc0ea1d8c85aabd8ef7107d8 [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"
msarettad8bcfe2016-03-07 07:09:03 -080011#include "SkColorSpace.h"
msaretteed039b2015-03-18 11:11:19 -070012#include "SkColorTable.h"
msarett74114382015-03-16 11:55:18 -070013#include "SkImageInfo.h"
msarett74114382015-03-16 11:55:18 -070014#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:
scroggodb30be22015-12-08 18:54:13 -080024 static bool IsBmp(const void*, size_t);
msarett74114382015-03-16 11:55:18 -070025
26 /*
msarett74114382015-03-16 11:55:18 -070027 * Assumes IsBmp was called and returned true
msarett9bde9182015-03-25 05:27:48 -070028 * Creates a bmp decoder
msarett74114382015-03-16 11:55:18 -070029 * Reads enough of the stream to determine the image format
msarett74114382015-03-16 11:55:18 -070030 */
31 static SkCodec* NewFromStream(SkStream*);
32
msarett9bde9182015-03-25 05:27:48 -070033 /*
msarett9bde9182015-03-25 05:27:48 -070034 * Creates a bmp decoder for a bmp embedded in ico
35 * Reads enough of the stream to determine the image format
msarett9bde9182015-03-25 05:27:48 -070036 */
37 static SkCodec* NewFromIco(SkStream*);
38
msarett74114382015-03-16 11:55:18 -070039protected:
40
msarettc30c4182016-04-20 11:53:35 -070041 SkBmpCodec(int width, int height, const SkEncodedInfo& info, SkStream* stream,
42 uint16_t bitsPerPixel, SkCodec::SkScanlineOrder rowOrder);
msarett74114382015-03-16 11:55:18 -070043
mtklein36352bf2015-03-25 18:17:31 -070044 SkEncodedFormat onGetEncodedFormat() const override { return kBMP_SkEncodedFormat; }
msarett9bde9182015-03-25 05:27:48 -070045
msarett74114382015-03-16 11:55:18 -070046 /*
scroggo79e378d2015-04-01 07:39:40 -070047 * Read enough of the stream to initialize the SkBmpCodec. Returns a bool
48 * representing success or failure. If it returned true, and codecOut was
halcanary96fcdcc2015-08-27 07:41:13 -070049 * not nullptr, it will be set to a new SkBmpCodec.
scroggo0a7e69c2015-04-03 07:22:22 -070050 * Does *not* take ownership of the passed in SkStream.
scroggo79e378d2015-04-01 07:39:40 -070051 */
msarett4ab9d5f2015-08-06 15:34:42 -070052 static bool ReadHeader(SkStream*, bool inIco, SkCodec** codecOut);
scroggo79e378d2015-04-01 07:39:40 -070053
scroggob427db12015-08-12 07:24:13 -070054 bool onRewind() override;
55
scroggo79e378d2015-04-01 07:39:40 -070056 /*
scroggob427db12015-08-12 07:24:13 -070057 * Returns whether this BMP is part of an ICO image.
msarett74114382015-03-16 11:55:18 -070058 */
scroggob427db12015-08-12 07:24:13 -070059 bool inIco() const {
60 return this->onInIco();
61 }
62
63 virtual bool onInIco() const {
64 return false;
65 }
msarett74114382015-03-16 11:55:18 -070066
67 /*
msarett5406d6f2015-08-31 06:55:13 -070068 * Get the destination row number corresponding to the encoded row number.
69 * For kTopDown, we simply return y, but for kBottomUp, the rows will be
70 * decoded in reverse order.
71 *
72 * @param y Iterates from 0 to height, indicating the current row.
73 * @param height The height of the current subset of the image that we are
74 * decoding. This is generally equal to the full height
75 * when we want to decode the full or one when we are
76 * sampling.
77 */
scroggo46c57472015-09-30 08:57:13 -070078 int32_t getDstRow(int32_t y, int32_t height) const;
msarett5406d6f2015-08-31 06:55:13 -070079
80 /*
msarett4ab9d5f2015-08-06 15:34:42 -070081 * Accessors used by subclasses
msarett74114382015-03-16 11:55:18 -070082 */
msarett4ab9d5f2015-08-06 15:34:42 -070083 uint16_t bitsPerPixel() const { return fBitsPerPixel; }
scroggo46c57472015-09-30 08:57:13 -070084 SkScanlineOrder onGetScanlineOrder() const override { return fRowOrder; }
msarett9b9497e2016-02-11 13:29:36 -080085 size_t srcRowBytes() const { return fSrcRowBytes; }
msarett5406d6f2015-08-31 06:55:13 -070086
87 /*
88 * To be overriden by bmp subclasses, which provide unique implementations.
89 * Performs subclass specific setup.
90 *
91 * @param dstInfo Contains output information. Height specifies
92 * the total number of rows that will be decoded.
93 * @param options Additonal options to pass to the decoder.
94 * @param inputColorPtr Client-provided memory for a color table. Must
95 * be enough for 256 colors. This will be
96 * populated with colors if the encoded image uses
97 * a color table.
98 * @param inputColorCount If the encoded image uses a color table, this
99 * will be set to the number of colors in the
100 * color table.
101 */
102 virtual SkCodec::Result prepareToDecode(const SkImageInfo& dstInfo,
103 const SkCodec::Options& options, SkPMColor inputColorPtr[],
104 int* inputColorCount) = 0;
msarett4ab9d5f2015-08-06 15:34:42 -0700105
106private:
msarett74114382015-03-16 11:55:18 -0700107
108 /*
msarett4ab9d5f2015-08-06 15:34:42 -0700109 * Creates a bmp decoder
110 * Reads enough of the stream to determine the image format
msarett74114382015-03-16 11:55:18 -0700111 */
msarett4ab9d5f2015-08-06 15:34:42 -0700112 static SkCodec* NewFromStream(SkStream*, bool inIco);
msarett74114382015-03-16 11:55:18 -0700113
msarett5406d6f2015-08-31 06:55:13 -0700114 /*
115 * Decodes the next dstInfo.height() lines.
116 *
117 * onGetPixels() uses this for full image decodes.
118 * SkScaledCodec::onGetPixels() uses the scanline decoder to call this with
119 * dstInfo.height() = 1, in order to implement sampling.
120 * A potential future use is to allow the caller to decode a subset of the
121 * lines in the image.
122 *
123 * @param dstInfo Contains output information. Height specifies the
124 * number of rows to decode at this time.
125 * @param dst Memory location to store output pixels
126 * @param dstRowBytes Bytes in a row of the destination
msarette6dd0042015-10-09 11:07:34 -0700127 * @return Number of rows successfully decoded
msarett5406d6f2015-08-31 06:55:13 -0700128 */
msarette6dd0042015-10-09 11:07:34 -0700129 virtual int decodeRows(const SkImageInfo& dstInfo, void* dst, size_t dstRowBytes,
msarett5406d6f2015-08-31 06:55:13 -0700130 const Options& opts) = 0;
131
msarett9b9497e2016-02-11 13:29:36 -0800132 virtual bool skipRows(int count);
133
scroggo46c57472015-09-30 08:57:13 -0700134 Result onStartScanlineDecode(const SkImageInfo& dstInfo, const SkCodec::Options&,
135 SkPMColor inputColorPtr[], int* inputColorCount) override;
msarett5406d6f2015-08-31 06:55:13 -0700136
msarette6dd0042015-10-09 11:07:34 -0700137 int onGetScanlines(void* dst, int count, size_t rowBytes) override;
scroggo46c57472015-09-30 08:57:13 -0700138
msarett9b9497e2016-02-11 13:29:36 -0800139 bool onSkipScanlines(int count) override;
scroggo46c57472015-09-30 08:57:13 -0700140
141 const uint16_t fBitsPerPixel;
142 const SkScanlineOrder fRowOrder;
msarett9b9497e2016-02-11 13:29:36 -0800143 const size_t fSrcRowBytes;
msarett74114382015-03-16 11:55:18 -0700144
145 typedef SkCodec INHERITED;
146};
msarett4ab9d5f2015-08-06 15:34:42 -0700147
148#endif