1*c8dee2aaSAndroid Build Coastguard Worker /* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2015 Google Inc. 3*c8dee2aaSAndroid Build Coastguard Worker * 4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be 5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file. 6*c8dee2aaSAndroid Build Coastguard Worker */ 7*c8dee2aaSAndroid Build Coastguard Worker #ifndef SkBmpCodec_DEFINED 8*c8dee2aaSAndroid Build Coastguard Worker #define SkBmpCodec_DEFINED 9*c8dee2aaSAndroid Build Coastguard Worker 10*c8dee2aaSAndroid Build Coastguard Worker #include "include/codec/SkCodec.h" 11*c8dee2aaSAndroid Build Coastguard Worker #include "include/codec/SkEncodedImageFormat.h" 12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColorType.h" 13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypes.h" 14*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skcms/skcms.h" 15*c8dee2aaSAndroid Build Coastguard Worker 16*c8dee2aaSAndroid Build Coastguard Worker #include <cstddef> 17*c8dee2aaSAndroid Build Coastguard Worker #include <cstdint> 18*c8dee2aaSAndroid Build Coastguard Worker #include <memory> 19*c8dee2aaSAndroid Build Coastguard Worker 20*c8dee2aaSAndroid Build Coastguard Worker class SkStream; 21*c8dee2aaSAndroid Build Coastguard Worker struct SkEncodedInfo; 22*c8dee2aaSAndroid Build Coastguard Worker struct SkImageInfo; 23*c8dee2aaSAndroid Build Coastguard Worker 24*c8dee2aaSAndroid Build Coastguard Worker /* 25*c8dee2aaSAndroid Build Coastguard Worker * This class enables code sharing between its bmp codec subclasses. The 26*c8dee2aaSAndroid Build Coastguard Worker * subclasses actually do the work. 27*c8dee2aaSAndroid Build Coastguard Worker */ 28*c8dee2aaSAndroid Build Coastguard Worker class SkBmpCodec : public SkCodec { 29*c8dee2aaSAndroid Build Coastguard Worker public: 30*c8dee2aaSAndroid Build Coastguard Worker static bool IsBmp(const void*, size_t); 31*c8dee2aaSAndroid Build Coastguard Worker 32*c8dee2aaSAndroid Build Coastguard Worker /* 33*c8dee2aaSAndroid Build Coastguard Worker * Assumes IsBmp was called and returned true 34*c8dee2aaSAndroid Build Coastguard Worker * Creates a bmp decoder 35*c8dee2aaSAndroid Build Coastguard Worker * Reads enough of the stream to determine the image format 36*c8dee2aaSAndroid Build Coastguard Worker */ 37*c8dee2aaSAndroid Build Coastguard Worker static std::unique_ptr<SkCodec> MakeFromStream(std::unique_ptr<SkStream>, Result*); 38*c8dee2aaSAndroid Build Coastguard Worker 39*c8dee2aaSAndroid Build Coastguard Worker /* 40*c8dee2aaSAndroid Build Coastguard Worker * Creates a bmp decoder for a bmp embedded in ico 41*c8dee2aaSAndroid Build Coastguard Worker * Reads enough of the stream to determine the image format 42*c8dee2aaSAndroid Build Coastguard Worker */ 43*c8dee2aaSAndroid Build Coastguard Worker static std::unique_ptr<SkCodec> MakeFromIco(std::unique_ptr<SkStream>, Result*); 44*c8dee2aaSAndroid Build Coastguard Worker 45*c8dee2aaSAndroid Build Coastguard Worker protected: 46*c8dee2aaSAndroid Build Coastguard Worker 47*c8dee2aaSAndroid Build Coastguard Worker SkBmpCodec(SkEncodedInfo&& info, std::unique_ptr<SkStream>, 48*c8dee2aaSAndroid Build Coastguard Worker uint16_t bitsPerPixel, SkCodec::SkScanlineOrder rowOrder); 49*c8dee2aaSAndroid Build Coastguard Worker onGetEncodedFormat()50*c8dee2aaSAndroid Build Coastguard Worker SkEncodedImageFormat onGetEncodedFormat() const override { return SkEncodedImageFormat::kBMP; } 51*c8dee2aaSAndroid Build Coastguard Worker 52*c8dee2aaSAndroid Build Coastguard Worker /* 53*c8dee2aaSAndroid Build Coastguard Worker * Read enough of the stream to initialize the SkBmpCodec. 54*c8dee2aaSAndroid Build Coastguard Worker * On kSuccess, if codecOut is not nullptr, it will be set to a new SkBmpCodec. 55*c8dee2aaSAndroid Build Coastguard Worker */ 56*c8dee2aaSAndroid Build Coastguard Worker static Result ReadHeader(SkStream*, bool inIco, std::unique_ptr<SkCodec>* codecOut); 57*c8dee2aaSAndroid Build Coastguard Worker 58*c8dee2aaSAndroid Build Coastguard Worker bool onRewind() override; 59*c8dee2aaSAndroid Build Coastguard Worker 60*c8dee2aaSAndroid Build Coastguard Worker /* 61*c8dee2aaSAndroid Build Coastguard Worker * Returns whether this BMP is part of an ICO image. 62*c8dee2aaSAndroid Build Coastguard Worker */ inIco()63*c8dee2aaSAndroid Build Coastguard Worker bool inIco() const { 64*c8dee2aaSAndroid Build Coastguard Worker return this->onInIco(); 65*c8dee2aaSAndroid Build Coastguard Worker } 66*c8dee2aaSAndroid Build Coastguard Worker onInIco()67*c8dee2aaSAndroid Build Coastguard Worker virtual bool onInIco() const { 68*c8dee2aaSAndroid Build Coastguard Worker return false; 69*c8dee2aaSAndroid Build Coastguard Worker } 70*c8dee2aaSAndroid Build Coastguard Worker 71*c8dee2aaSAndroid Build Coastguard Worker /* 72*c8dee2aaSAndroid Build Coastguard Worker * Get the destination row number corresponding to the encoded row number. 73*c8dee2aaSAndroid Build Coastguard Worker * For kTopDown, we simply return y, but for kBottomUp, the rows will be 74*c8dee2aaSAndroid Build Coastguard Worker * decoded in reverse order. 75*c8dee2aaSAndroid Build Coastguard Worker * 76*c8dee2aaSAndroid Build Coastguard Worker * @param y Iterates from 0 to height, indicating the current row. 77*c8dee2aaSAndroid Build Coastguard Worker * @param height The height of the current subset of the image that we are 78*c8dee2aaSAndroid Build Coastguard Worker * decoding. This is generally equal to the full height 79*c8dee2aaSAndroid Build Coastguard Worker * when we want to decode the full or one when we are 80*c8dee2aaSAndroid Build Coastguard Worker * sampling. 81*c8dee2aaSAndroid Build Coastguard Worker */ 82*c8dee2aaSAndroid Build Coastguard Worker int32_t getDstRow(int32_t y, int32_t height) const; 83*c8dee2aaSAndroid Build Coastguard Worker 84*c8dee2aaSAndroid Build Coastguard Worker /* 85*c8dee2aaSAndroid Build Coastguard Worker * Accessors used by subclasses 86*c8dee2aaSAndroid Build Coastguard Worker */ bitsPerPixel()87*c8dee2aaSAndroid Build Coastguard Worker uint16_t bitsPerPixel() const { return fBitsPerPixel; } onGetScanlineOrder()88*c8dee2aaSAndroid Build Coastguard Worker SkScanlineOrder onGetScanlineOrder() const override { return fRowOrder; } srcRowBytes()89*c8dee2aaSAndroid Build Coastguard Worker size_t srcRowBytes() const { return fSrcRowBytes; } 90*c8dee2aaSAndroid Build Coastguard Worker 91*c8dee2aaSAndroid Build Coastguard Worker /* 92*c8dee2aaSAndroid Build Coastguard Worker * To be overriden by bmp subclasses, which provide unique implementations. 93*c8dee2aaSAndroid Build Coastguard Worker * Performs subclass specific setup. 94*c8dee2aaSAndroid Build Coastguard Worker * 95*c8dee2aaSAndroid Build Coastguard Worker * @param dstInfo Contains output information. Height specifies 96*c8dee2aaSAndroid Build Coastguard Worker * the total number of rows that will be decoded. 97*c8dee2aaSAndroid Build Coastguard Worker * @param options Additonal options to pass to the decoder. 98*c8dee2aaSAndroid Build Coastguard Worker */ 99*c8dee2aaSAndroid Build Coastguard Worker virtual SkCodec::Result onPrepareToDecode(const SkImageInfo& dstInfo, 100*c8dee2aaSAndroid Build Coastguard Worker const SkCodec::Options& options) = 0; 101*c8dee2aaSAndroid Build Coastguard Worker SkCodec::Result prepareToDecode(const SkImageInfo& dstInfo, 102*c8dee2aaSAndroid Build Coastguard Worker const SkCodec::Options& options); 103*c8dee2aaSAndroid Build Coastguard Worker xformBuffer()104*c8dee2aaSAndroid Build Coastguard Worker uint32_t* xformBuffer() const { return fXformBuffer.get(); } resetXformBuffer(int count)105*c8dee2aaSAndroid Build Coastguard Worker void resetXformBuffer(int count) { fXformBuffer.reset(new uint32_t[count]); } 106*c8dee2aaSAndroid Build Coastguard Worker 107*c8dee2aaSAndroid Build Coastguard Worker /* 108*c8dee2aaSAndroid Build Coastguard Worker * BMPs are typically encoded as BGRA/BGR so this is a more efficient choice 109*c8dee2aaSAndroid Build Coastguard Worker * than RGBA. 110*c8dee2aaSAndroid Build Coastguard Worker */ 111*c8dee2aaSAndroid Build Coastguard Worker inline static constexpr SkColorType kXformSrcColorType = kBGRA_8888_SkColorType; 112*c8dee2aaSAndroid Build Coastguard Worker inline static constexpr auto kXformSrcColorFormat = skcms_PixelFormat_BGRA_8888; 113*c8dee2aaSAndroid Build Coastguard Worker 114*c8dee2aaSAndroid Build Coastguard Worker private: 115*c8dee2aaSAndroid Build Coastguard Worker 116*c8dee2aaSAndroid Build Coastguard Worker /* 117*c8dee2aaSAndroid Build Coastguard Worker * Creates a bmp decoder 118*c8dee2aaSAndroid Build Coastguard Worker * Reads enough of the stream to determine the image format 119*c8dee2aaSAndroid Build Coastguard Worker */ 120*c8dee2aaSAndroid Build Coastguard Worker static std::unique_ptr<SkCodec> MakeFromStream(std::unique_ptr<SkStream>, Result*, bool inIco); 121*c8dee2aaSAndroid Build Coastguard Worker 122*c8dee2aaSAndroid Build Coastguard Worker /* 123*c8dee2aaSAndroid Build Coastguard Worker * Decodes the next dstInfo.height() lines. 124*c8dee2aaSAndroid Build Coastguard Worker * 125*c8dee2aaSAndroid Build Coastguard Worker * onGetPixels() uses this for full image decodes. 126*c8dee2aaSAndroid Build Coastguard Worker * SkScaledCodec::onGetPixels() uses the scanline decoder to call this with 127*c8dee2aaSAndroid Build Coastguard Worker * dstInfo.height() = 1, in order to implement sampling. 128*c8dee2aaSAndroid Build Coastguard Worker * A potential future use is to allow the caller to decode a subset of the 129*c8dee2aaSAndroid Build Coastguard Worker * lines in the image. 130*c8dee2aaSAndroid Build Coastguard Worker * 131*c8dee2aaSAndroid Build Coastguard Worker * @param dstInfo Contains output information. Height specifies the 132*c8dee2aaSAndroid Build Coastguard Worker * number of rows to decode at this time. 133*c8dee2aaSAndroid Build Coastguard Worker * @param dst Memory location to store output pixels 134*c8dee2aaSAndroid Build Coastguard Worker * @param dstRowBytes Bytes in a row of the destination 135*c8dee2aaSAndroid Build Coastguard Worker * @return Number of rows successfully decoded 136*c8dee2aaSAndroid Build Coastguard Worker */ 137*c8dee2aaSAndroid Build Coastguard Worker virtual int decodeRows(const SkImageInfo& dstInfo, void* dst, size_t dstRowBytes, 138*c8dee2aaSAndroid Build Coastguard Worker const Options& opts) = 0; 139*c8dee2aaSAndroid Build Coastguard Worker 140*c8dee2aaSAndroid Build Coastguard Worker virtual bool skipRows(int count); 141*c8dee2aaSAndroid Build Coastguard Worker 142*c8dee2aaSAndroid Build Coastguard Worker Result onStartScanlineDecode(const SkImageInfo& dstInfo, 143*c8dee2aaSAndroid Build Coastguard Worker const SkCodec::Options&) override; 144*c8dee2aaSAndroid Build Coastguard Worker 145*c8dee2aaSAndroid Build Coastguard Worker int onGetScanlines(void* dst, int count, size_t rowBytes) override; 146*c8dee2aaSAndroid Build Coastguard Worker 147*c8dee2aaSAndroid Build Coastguard Worker bool onSkipScanlines(int count) override; 148*c8dee2aaSAndroid Build Coastguard Worker 149*c8dee2aaSAndroid Build Coastguard Worker const uint16_t fBitsPerPixel; 150*c8dee2aaSAndroid Build Coastguard Worker const SkScanlineOrder fRowOrder; 151*c8dee2aaSAndroid Build Coastguard Worker const size_t fSrcRowBytes; 152*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<uint32_t[]> fXformBuffer; 153*c8dee2aaSAndroid Build Coastguard Worker 154*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = SkCodec; 155*c8dee2aaSAndroid Build Coastguard Worker }; 156*c8dee2aaSAndroid Build Coastguard Worker 157*c8dee2aaSAndroid Build Coastguard Worker #endif 158