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. setIdatLength(size_t len)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 { voidpvoidp38 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; onGetEncodedFormat()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 png_ptr()60 voidp png_ptr() { return fPng_ptr; } info_ptr()61 voidp info_ptr() { return fInfo_ptr; } 62 swizzler()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