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*, SkPngChunkReader* = NULL);
     27 
     28     // FIXME (scroggo): Temporarily needed by AutoCleanPng.
     29     void setIdatLength(size_t len) { fIdatLength = len; }
     30 
     31     ~SkPngCodec() override;
     32 
     33 protected:
     34     // We hold the png_ptr and info_ptr as voidp to avoid having to include png.h
     35     // or forward declare their types here.  voidp auto-casts to the real pointer types.
     36     struct voidp {
     37         voidp(void* ptr) : fPtr(ptr) {}
     38 
     39         template <typename T>
     40         operator T*() const { return (T*)fPtr; }
     41 
     42         explicit operator bool() const { return fPtr != nullptr; }
     43 
     44         void* fPtr;
     45     };
     46 
     47     SkPngCodec(const SkEncodedInfo&, const SkImageInfo&, SkStream*, SkPngChunkReader*,
     48             void* png_ptr, void* info_ptr, int bitDepth);
     49 
     50     Result onGetPixels(const SkImageInfo&, void*, size_t, const Options&, SkPMColor*, int*, int*)
     51             override;
     52     SkEncodedImageFormat onGetEncodedFormat() const override { return SkEncodedImageFormat::kPNG; }
     53     bool onRewind() override;
     54     uint64_t onGetFillValue(const SkImageInfo&) const override;
     55 
     56     SkSampler* getSampler(bool createIfNecessary) override;
     57     void applyXformRow(void* dst, const void* src);
     58 
     59     voidp png_ptr() { return fPng_ptr; }
     60     voidp info_ptr() { return fInfo_ptr; }
     61 
     62     SkSwizzler* swizzler() { return fSwizzler.get(); }
     63 
     64     // Initialize variables used by applyXformRow.
     65     void initializeXformParams();
     66 
     67     /**
     68      *  Pass available input to libpng to process it.
     69      *
     70      *  libpng will call any relevant callbacks installed. This will continue decoding
     71      *  until it reaches the end of the file, or until a callback tells libpng to stop.
     72      */
     73     void processData();
     74 
     75     Result onStartIncrementalDecode(const SkImageInfo& dstInfo, void* pixels, size_t rowBytes,
     76             const SkCodec::Options&,
     77             SkPMColor* ctable, int* ctableCount) 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, int* ctableCount);
    105     // Helper to set up swizzler, color xforms, and color table. Also calls png_read_update_info.
    106     bool initializeXforms(const SkImageInfo& dstInfo, const Options&, SkPMColor* colorPtr,
    107                           int* colorCount);
    108     void initializeSwizzler(const SkImageInfo& dstInfo, const Options&, bool skipFormatConversion);
    109     void allocateStorage(const SkImageInfo& dstInfo);
    110     void destroyReadStruct();
    111 
    112     virtual Result decodeAllRows(void* dst, size_t rowBytes, int* rowsDecoded) = 0;
    113     virtual void setRange(int firstRow, int lastRow, void* dst, size_t rowBytes) = 0;
    114     virtual Result decode(int* rowsDecoded) = 0;
    115 
    116     XformMode                      fXformMode;
    117     SkColorSpaceXform::ColorFormat fXformColorFormat;
    118     SkAlphaType                    fXformAlphaType;
    119     int                            fXformWidth;
    120 
    121     size_t                         fIdatLength;
    122     bool                           fDecodedIdat;
    123 
    124     typedef SkCodec INHERITED;
    125 };
    126 #endif  // SkPngCodec_DEFINED
    127