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 
      8 #ifndef SkJpegCodec_DEFINED
      9 #define SkJpegCodec_DEFINED
     10 
     11 #include "SkCodec.h"
     12 #include "SkImageInfo.h"
     13 #include "SkSwizzler.h"
     14 #include "SkStream.h"
     15 #include "SkTemplates.h"
     16 
     17 class JpegDecoderMgr;
     18 
     19 /*
     20  *
     21  * This class implements the decoding for jpeg images
     22  *
     23  */
     24 class SkJpegCodec : public SkCodec {
     25 public:
     26     static bool IsJpeg(const void*, size_t);
     27 
     28     /*
     29      * Assumes IsJpeg was called and returned true
     30      * Creates a jpeg decoder
     31      * Takes ownership of the stream
     32      */
     33     static SkCodec* NewFromStream(SkStream*);
     34 
     35 protected:
     36 
     37     /*
     38      * Recommend a set of destination dimensions given a requested scale
     39      */
     40     SkISize onGetScaledDimensions(float desiredScale) const override;
     41 
     42     /*
     43      * Initiates the jpeg decode
     44      */
     45     Result onGetPixels(const SkImageInfo& dstInfo, void* dst, size_t dstRowBytes, const Options&,
     46             SkPMColor*, int*, int*) override;
     47 
     48     bool onQueryYUV8(YUVSizeInfo* sizeInfo, SkYUVColorSpace* colorSpace) const override;
     49 
     50     Result onGetYUV8Planes(const YUVSizeInfo& sizeInfo, void* pixels[3]) override;
     51 
     52     SkEncodedFormat onGetEncodedFormat() const override {
     53         return kJPEG_SkEncodedFormat;
     54     }
     55 
     56     bool onRewind() override;
     57 
     58     bool onDimensionsSupported(const SkISize&) override;
     59 
     60 private:
     61 
     62     /*
     63      * Read enough of the stream to initialize the SkJpegCodec.
     64      * Returns a bool representing success or failure.
     65      *
     66      * @param codecOut
     67      * If this returns true, and codecOut was not nullptr,
     68      * codecOut will be set to a new SkJpegCodec.
     69      *
     70      * @param decoderMgrOut
     71      * If this returns true, and codecOut was nullptr,
     72      * decoderMgrOut must be non-nullptr and decoderMgrOut will be set to a new
     73      * JpegDecoderMgr pointer.
     74      *
     75      * @param stream
     76      * Deleted on failure.
     77      * codecOut will take ownership of it in the case where we created a codec.
     78      * Ownership is unchanged when we set decoderMgrOut.
     79      *
     80      */
     81     static bool ReadHeader(SkStream* stream, SkCodec** codecOut,
     82             JpegDecoderMgr** decoderMgrOut);
     83 
     84     /*
     85      * Creates an instance of the decoder
     86      * Called only by NewFromStream
     87      *
     88      * @param srcInfo contains the source width and height
     89      * @param stream the encoded image data
     90      * @param decoderMgr holds decompress struct, src manager, and error manager
     91      *                   takes ownership
     92      */
     93     SkJpegCodec(const SkImageInfo& srcInfo, SkStream* stream, JpegDecoderMgr* decoderMgr);
     94 
     95     /*
     96      * Checks if the conversion between the input image and the requested output
     97      * image has been implemented
     98      * Sets the output color space
     99      */
    100     bool setOutputColorSpace(const SkImageInfo& dst);
    101 
    102     // scanline decoding
    103     void initializeSwizzler(const SkImageInfo& dstInfo, const Options& options);
    104     SkSampler* getSampler(bool createIfNecessary) override;
    105     Result onStartScanlineDecode(const SkImageInfo& dstInfo, const Options& options,
    106             SkPMColor ctable[], int* ctableCount) override;
    107     int onGetScanlines(void* dst, int count, size_t rowBytes) override;
    108     bool onSkipScanlines(int count) override;
    109 
    110     SkAutoTDelete<JpegDecoderMgr> fDecoderMgr;
    111     // We will save the state of the decompress struct after reading the header.
    112     // This allows us to safely call onGetScaledDimensions() at any time.
    113     const int                     fReadyState;
    114 
    115     // scanline decoding
    116     SkAutoTMalloc<uint8_t>     fStorage;    // Only used if sampling is needed
    117     uint8_t*                   fSrcRow;     // Only used if sampling is needed
    118     // libjpeg-turbo provides some subsetting.  In the case that libjpeg-turbo
    119     // cannot take the exact the subset that we need, we will use the swizzler
    120     // to further subset the output from libjpeg-turbo.
    121     SkIRect                    fSwizzlerSubset;
    122     SkAutoTDelete<SkSwizzler>  fSwizzler;
    123 
    124     typedef SkCodec INHERITED;
    125 };
    126 
    127 #endif
    128