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 SkPngCodec_DEFINED
      8 #define SkPngCodec_DEFINED
      9 
     10 #include "SkCodec.h"
     11 #include "SkColorSpaceXform.h"
     12 #include "SkColorTable.h"
     13 #include "SkPngChunkReader.h"
     14 #include "SkEncodedImageFormat.h"
     15 #include "SkImageInfo.h"
     16 #include "SkRefCnt.h"
     17 #include "SkSwizzler.h"
     18 
     19 class SkStream;
     20 
     21 class SkPngCodec : public SkCodec {
     22 public:
     23     static bool IsPng(const char*, size_t);
     24 
     25     // Assume IsPng was called and returned true.
     26     static SkCodec* NewFromStream(SkStream*, Result*,
     27                                   SkPngChunkReader* = nullptr);
     28 
     29     // FIXME (scroggo): Temporarily needed by AutoCleanPng.
     30     void setIdatLength(size_t len) { fIdatLength = len; }
     31 
     32     ~SkPngCodec() override;
     33 
     34 protected:
     35     // We hold the png_ptr and info_ptr as voidp to avoid having to include png.h
     36     // or forward declare their types here.  voidp auto-casts to the real pointer types.
     37     struct voidp {
     38         voidp(void* ptr) : fPtr(ptr) {}
     39 
     40         template <typename T>
     41         operator T*() const { return (T*)fPtr; }
     42 
     43         explicit operator bool() const { return fPtr != nullptr; }
     44 
     45         void* fPtr;
     46     };
     47 
     48     SkPngCodec(const SkEncodedInfo&, const SkImageInfo&, SkStream*, SkPngChunkReader*,
     49             void* png_ptr, void* info_ptr, int bitDepth);
     50 
     51     Result onGetPixels(const SkImageInfo&, void*, size_t, const Options&, int*)
     52             override;
     53     SkEncodedImageFormat onGetEncodedFormat() const override { return SkEncodedImageFormat::kPNG; }
     54     bool onRewind() override;
     55     uint64_t onGetFillValue(const SkImageInfo&) const override;
     56 
     57     SkSampler* getSampler(bool createIfNecessary) override;
     58     void applyXformRow(void* dst, const void* src);
     59 
     60     voidp png_ptr() { return fPng_ptr; }
     61     voidp info_ptr() { return fInfo_ptr; }
     62 
     63     SkSwizzler* swizzler() { return fSwizzler.get(); }
     64 
     65     // Initialize variables used by applyXformRow.
     66     void initializeXformParams();
     67 
     68     /**
     69      *  Pass available input to libpng to process it.
     70      *
     71      *  libpng will call any relevant callbacks installed. This will continue decoding
     72      *  until it reaches the end of the file, or until a callback tells libpng to stop.
     73      */
     74     void processData();
     75 
     76     Result onStartIncrementalDecode(const SkImageInfo& dstInfo, void* pixels, size_t rowBytes,
     77             const SkCodec::Options&) override;
     78     Result onIncrementalDecode(int*) override;
     79 
     80     sk_sp<SkPngChunkReader>     fPngChunkReader;
     81     voidp                       fPng_ptr;
     82     voidp                       fInfo_ptr;
     83 
     84     // These are stored here so they can be used both by normal decoding and scanline decoding.
     85     sk_sp<SkColorTable>         fColorTable;    // May be unpremul.
     86     std::unique_ptr<SkSwizzler> fSwizzler;
     87     SkAutoTMalloc<uint8_t>      fStorage;
     88     void*                       fColorXformSrcRow;
     89     const int                   fBitDepth;
     90 
     91 private:
     92 
     93     enum XformMode {
     94         // Requires only a swizzle pass.
     95         kSwizzleOnly_XformMode,
     96 
     97         // Requires only a color xform pass.
     98         kColorOnly_XformMode,
     99 
    100         // Requires a swizzle and a color xform.
    101         kSwizzleColor_XformMode,
    102     };
    103 
    104     bool createColorTable(const SkImageInfo& dstInfo);
    105     // Helper to set up swizzler, color xforms, and color table. Also calls png_read_update_info.
    106     SkCodec::Result initializeXforms(const SkImageInfo& dstInfo, const Options&);
    107     void initializeSwizzler(const SkImageInfo& dstInfo, const Options&, bool skipFormatConversion);
    108     void allocateStorage(const SkImageInfo& dstInfo);
    109     void destroyReadStruct();
    110 
    111     virtual Result decodeAllRows(void* dst, size_t rowBytes, int* rowsDecoded) = 0;
    112     virtual void setRange(int firstRow, int lastRow, void* dst, size_t rowBytes) = 0;
    113     virtual Result decode(int* rowsDecoded) = 0;
    114 
    115     XformMode                      fXformMode;
    116     int                            fXformWidth;
    117 
    118     size_t                         fIdatLength;
    119     bool                           fDecodedIdat;
    120 
    121     typedef SkCodec INHERITED;
    122 };
    123 #endif  // SkPngCodec_DEFINED
    124