Home | History | Annotate | Download | only in codec
      1 /*
      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  */
      7 #ifndef SkBmpCodec_DEFINED
      8 #define SkBmpCodec_DEFINED
      9 
     10 #include "SkCodec.h"
     11 #include "SkColorTable.h"
     12 #include "SkImageInfo.h"
     13 #include "SkStream.h"
     14 #include "SkSwizzler.h"
     15 #include "SkTypes.h"
     16 
     17 /*
     18  * This class enables code sharing between its bmp codec subclasses.  The
     19  * subclasses actually do the work.
     20  */
     21 class SkBmpCodec : public SkCodec {
     22 public:
     23     static bool IsBmp(const void*, size_t);
     24 
     25     /*
     26      * Assumes IsBmp was called and returned true
     27      * Creates a bmp decoder
     28      * Reads enough of the stream to determine the image format
     29      */
     30     static SkCodec* NewFromStream(SkStream*);
     31 
     32     /*
     33      * Creates a bmp decoder for a bmp embedded in ico
     34      * Reads enough of the stream to determine the image format
     35      */
     36     static SkCodec* NewFromIco(SkStream*);
     37 
     38 protected:
     39 
     40     SkBmpCodec(const SkImageInfo& info, SkStream* stream, uint16_t bitsPerPixel,
     41             SkCodec::SkScanlineOrder rowOrder);
     42 
     43     SkEncodedFormat onGetEncodedFormat() const override { return kBMP_SkEncodedFormat; }
     44 
     45     /*
     46      * Read enough of the stream to initialize the SkBmpCodec. Returns a bool
     47      * representing success or failure. If it returned true, and codecOut was
     48      * not nullptr, it will be set to a new SkBmpCodec.
     49      * Does *not* take ownership of the passed in SkStream.
     50      */
     51     static bool ReadHeader(SkStream*, bool inIco, SkCodec** codecOut);
     52 
     53     bool onRewind() override;
     54 
     55     /*
     56      * Returns whether this BMP is part of an ICO image.
     57      */
     58     bool inIco() const {
     59         return this->onInIco();
     60     }
     61 
     62     virtual bool onInIco() const {
     63         return false;
     64     }
     65 
     66     /*
     67      * 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      */
     77     int32_t getDstRow(int32_t y, int32_t height) const;
     78 
     79     /*
     80      * Accessors used by subclasses
     81      */
     82     uint16_t bitsPerPixel() const { return fBitsPerPixel; }
     83     SkScanlineOrder onGetScanlineOrder() const override { return fRowOrder; }
     84     size_t srcRowBytes() const { return fSrcRowBytes; }
     85 
     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;
    104 
    105 private:
    106 
    107     /*
    108      * Creates a bmp decoder
    109      * Reads enough of the stream to determine the image format
    110      */
    111     static SkCodec* NewFromStream(SkStream*, bool inIco);
    112 
    113     /*
    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
    126      * @return            Number of rows successfully decoded
    127      */
    128     virtual int decodeRows(const SkImageInfo& dstInfo, void* dst, size_t dstRowBytes,
    129             const Options& opts) = 0;
    130 
    131     virtual bool skipRows(int count);
    132 
    133     Result onStartScanlineDecode(const SkImageInfo& dstInfo, const SkCodec::Options&,
    134             SkPMColor inputColorPtr[], int* inputColorCount) override;
    135 
    136     int onGetScanlines(void* dst, int count, size_t rowBytes) override;
    137 
    138     bool onSkipScanlines(int count) override;
    139 
    140     const uint16_t          fBitsPerPixel;
    141     const SkScanlineOrder   fRowOrder;
    142     const size_t            fSrcRowBytes;
    143 
    144     typedef SkCodec INHERITED;
    145 };
    146 
    147 #endif
    148