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