blob: 3196ae11266da620a6bcb7272fb52cd801bf00be [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 */
Mike Reedede7bac2017-07-23 15:30:02 -040031 static std::unique_ptr<SkCodec> MakeFromStream(std::unique_ptr<SkStream>, Result*);
msarett74114382015-03-16 11:55:18 -070032
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 */
Mike Reedede7bac2017-07-23 15:30:02 -040037 static std::unique_ptr<SkCodec> MakeFromIco(std::unique_ptr<SkStream>, Result*);
msarett9bde9182015-03-25 05:27:48 -070038
msarett74114382015-03-16 11:55:18 -070039protected:
40
Mike Reedede7bac2017-07-23 15:30:02 -040041 SkBmpCodec(int width, int height, const SkEncodedInfo& info, std::unique_ptr<SkStream>,
msarettc30c4182016-04-20 11:53:35 -070042 uint16_t bitsPerPixel, SkCodec::SkScanlineOrder rowOrder);
msarett74114382015-03-16 11:55:18 -070043
Hal Canarydb683012016-11-23 08:55:18 -070044 SkEncodedImageFormat onGetEncodedFormat() const override { return SkEncodedImageFormat::kBMP; }
msarett9bde9182015-03-25 05:27:48 -070045
msarett74114382015-03-16 11:55:18 -070046 /*
Leon Scroggins III588fb042017-07-14 16:32:31 -040047 * Read enough of the stream to initialize the SkBmpCodec.
48 * On kSuccess, if codecOut is not nullptr, it will be set to a new SkBmpCodec.
scroggo79e378d2015-04-01 07:39:40 -070049 */
Leon Scroggins III588fb042017-07-14 16:32:31 -040050 static Result ReadHeader(SkStream*, bool inIco, std::unique_ptr<SkCodec>* codecOut);
scroggo79e378d2015-04-01 07:39:40 -070051
scroggob427db12015-08-12 07:24:13 -070052 bool onRewind() override;
53
scroggo79e378d2015-04-01 07:39:40 -070054 /*
scroggob427db12015-08-12 07:24:13 -070055 * Returns whether this BMP is part of an ICO image.
msarett74114382015-03-16 11:55:18 -070056 */
scroggob427db12015-08-12 07:24:13 -070057 bool inIco() const {
58 return this->onInIco();
59 }
60
61 virtual bool onInIco() const {
62 return false;
63 }
msarett74114382015-03-16 11:55:18 -070064
65 /*
msarett5406d6f2015-08-31 06:55:13 -070066 * Get the destination row number corresponding to the encoded row number.
67 * For kTopDown, we simply return y, but for kBottomUp, the rows will be
68 * decoded in reverse order.
69 *
70 * @param y Iterates from 0 to height, indicating the current row.
71 * @param height The height of the current subset of the image that we are
72 * decoding. This is generally equal to the full height
73 * when we want to decode the full or one when we are
74 * sampling.
75 */
scroggo46c57472015-09-30 08:57:13 -070076 int32_t getDstRow(int32_t y, int32_t height) const;
msarett5406d6f2015-08-31 06:55:13 -070077
78 /*
msarett4ab9d5f2015-08-06 15:34:42 -070079 * Accessors used by subclasses
msarett74114382015-03-16 11:55:18 -070080 */
msarett4ab9d5f2015-08-06 15:34:42 -070081 uint16_t bitsPerPixel() const { return fBitsPerPixel; }
scroggo46c57472015-09-30 08:57:13 -070082 SkScanlineOrder onGetScanlineOrder() const override { return fRowOrder; }
msarett9b9497e2016-02-11 13:29:36 -080083 size_t srcRowBytes() const { return fSrcRowBytes; }
msarett5406d6f2015-08-31 06:55:13 -070084
85 /*
86 * To be overriden by bmp subclasses, which provide unique implementations.
87 * Performs subclass specific setup.
88 *
89 * @param dstInfo Contains output information. Height specifies
90 * the total number of rows that will be decoded.
91 * @param options Additonal options to pass to the decoder.
msarett5406d6f2015-08-31 06:55:13 -070092 */
Matt Sarett1b96c6f2016-11-03 16:15:20 -040093 virtual SkCodec::Result onPrepareToDecode(const SkImageInfo& dstInfo,
Leon Scroggins571b30f2017-07-11 17:35:31 +000094 const SkCodec::Options& options) = 0;
Matt Sarett1b96c6f2016-11-03 16:15:20 -040095 SkCodec::Result prepareToDecode(const SkImageInfo& dstInfo,
Leon Scroggins571b30f2017-07-11 17:35:31 +000096 const SkCodec::Options& options);
Matt Sarett1b96c6f2016-11-03 16:15:20 -040097
Matt Sarett1b96c6f2016-11-03 16:15:20 -040098 uint32_t* xformBuffer() const { return fXformBuffer.get(); }
99 void resetXformBuffer(int count) { fXformBuffer.reset(new uint32_t[count]); }
msarett4ab9d5f2015-08-06 15:34:42 -0700100
Matt Sarett562e6812016-11-08 16:13:43 -0500101 /*
102 * BMPs are typically encoded as BGRA/BGR so this is a more efficient choice
103 * than RGBA.
104 */
Leon Scroggins III862c1962017-10-02 16:28:49 -0400105 static constexpr SkColorType kXformSrcColorType = kBGRA_8888_SkColorType;
106 static constexpr auto kXformSrcColorFormat = SkColorSpaceXform::kBGRA_8888_ColorFormat;
Matt Sarett562e6812016-11-08 16:13:43 -0500107
msarett4ab9d5f2015-08-06 15:34:42 -0700108private:
msarett74114382015-03-16 11:55:18 -0700109
110 /*
msarett4ab9d5f2015-08-06 15:34:42 -0700111 * Creates a bmp decoder
112 * Reads enough of the stream to determine the image format
msarett74114382015-03-16 11:55:18 -0700113 */
Mike Reedede7bac2017-07-23 15:30:02 -0400114 static std::unique_ptr<SkCodec> MakeFromStream(std::unique_ptr<SkStream>, Result*, bool inIco);
msarett74114382015-03-16 11:55:18 -0700115
msarett5406d6f2015-08-31 06:55:13 -0700116 /*
117 * Decodes the next dstInfo.height() lines.
118 *
119 * onGetPixels() uses this for full image decodes.
120 * SkScaledCodec::onGetPixels() uses the scanline decoder to call this with
121 * dstInfo.height() = 1, in order to implement sampling.
122 * A potential future use is to allow the caller to decode a subset of the
123 * lines in the image.
124 *
125 * @param dstInfo Contains output information. Height specifies the
126 * number of rows to decode at this time.
127 * @param dst Memory location to store output pixels
128 * @param dstRowBytes Bytes in a row of the destination
msarette6dd0042015-10-09 11:07:34 -0700129 * @return Number of rows successfully decoded
msarett5406d6f2015-08-31 06:55:13 -0700130 */
msarette6dd0042015-10-09 11:07:34 -0700131 virtual int decodeRows(const SkImageInfo& dstInfo, void* dst, size_t dstRowBytes,
msarett5406d6f2015-08-31 06:55:13 -0700132 const Options& opts) = 0;
133
msarett9b9497e2016-02-11 13:29:36 -0800134 virtual bool skipRows(int count);
135
Leon Scroggins571b30f2017-07-11 17:35:31 +0000136 Result onStartScanlineDecode(const SkImageInfo& dstInfo,
137 const SkCodec::Options&) override;
msarett5406d6f2015-08-31 06:55:13 -0700138
msarette6dd0042015-10-09 11:07:34 -0700139 int onGetScanlines(void* dst, int count, size_t rowBytes) override;
scroggo46c57472015-09-30 08:57:13 -0700140
msarett9b9497e2016-02-11 13:29:36 -0800141 bool onSkipScanlines(int count) override;
scroggo46c57472015-09-30 08:57:13 -0700142
Matt Sarett1b96c6f2016-11-03 16:15:20 -0400143 const uint16_t fBitsPerPixel;
144 const SkScanlineOrder fRowOrder;
145 const size_t fSrcRowBytes;
146 std::unique_ptr<uint32_t[]> fXformBuffer;
msarett74114382015-03-16 11:55:18 -0700147
148 typedef SkCodec INHERITED;
149};
msarett4ab9d5f2015-08-06 15:34:42 -0700150
151#endif