OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkCodec.h" | 8 #include "SkCodec.h" |
9 #include "SkColorSpaceXform.h" | 9 #include "SkColorSpaceXform.h" |
10 #include "SkColorTable.h" | 10 #include "SkColorTable.h" |
11 #include "SkPngChunkReader.h" | 11 #include "SkPngChunkReader.h" |
12 #include "SkEncodedFormat.h" | 12 #include "SkEncodedFormat.h" |
13 #include "SkImageInfo.h" | 13 #include "SkImageInfo.h" |
14 #include "SkRefCnt.h" | 14 #include "SkRefCnt.h" |
15 #include "SkSwizzler.h" | 15 #include "SkSwizzler.h" |
16 | 16 |
| 17 // FIXME (scroggo): GOOGLE3 is currently using an outdated version of libpng, |
| 18 // so we need to work around the lack of the method png_process_data_pause. |
| 19 // This code will be unnecessary once we update GOOGLE3. It would make more |
| 20 // sense to condition this on the version of libpng being used, but we do not |
| 21 // know that here because png.h is only included by the cpp file. |
| 22 #define SK_GOOGLE3_PNG_HACK |
| 23 |
17 class SkStream; | 24 class SkStream; |
18 | 25 |
19 class SkPngCodec : public SkCodec { | 26 class SkPngCodec : public SkCodec { |
20 public: | 27 public: |
21 static bool IsPng(const char*, size_t); | 28 static bool IsPng(const char*, size_t); |
22 | 29 |
23 // Assume IsPng was called and returned true. | 30 // Assume IsPng was called and returned true. |
24 static SkCodec* NewFromStream(SkStream*, SkPngChunkReader* = NULL); | 31 static SkCodec* NewFromStream(SkStream*, SkPngChunkReader* = NULL); |
25 | 32 |
26 virtual ~SkPngCodec(); | 33 virtual ~SkPngCodec(); |
27 | 34 |
28 protected: | 35 protected: |
29 // We hold the png_ptr and info_ptr as voidp to avoid having to include png.
h | 36 // We hold the png_ptr and info_ptr as voidp to avoid having to include png.
h |
30 // or forward declare their types here. voidp auto-casts to the real pointe
r types. | 37 // or forward declare their types here. voidp auto-casts to the real pointe
r types. |
31 struct voidp { | 38 struct voidp { |
32 voidp(void* ptr) : fPtr(ptr) {} | 39 voidp(void* ptr) : fPtr(ptr) {} |
33 | 40 |
34 template <typename T> | 41 template <typename T> |
35 operator T*() const { return (T*)fPtr; } | 42 operator T*() const { return (T*)fPtr; } |
36 | 43 |
37 explicit operator bool() const { return fPtr != nullptr; } | 44 explicit operator bool() const { return fPtr != nullptr; } |
38 | 45 |
39 void* fPtr; | 46 void* fPtr; |
40 }; | 47 }; |
41 | 48 |
| 49 SkPngCodec(const SkEncodedInfo&, const SkImageInfo&, SkStream*, SkPngChunkRe
ader*, |
| 50 void* png_ptr, void* info_ptr, int bitDepth); |
| 51 |
42 Result onGetPixels(const SkImageInfo&, void*, size_t, const Options&, SkPMCo
lor*, int*, int*) | 52 Result onGetPixels(const SkImageInfo&, void*, size_t, const Options&, SkPMCo
lor*, int*, int*) |
43 override; | 53 override; |
44 SkEncodedFormat onGetEncodedFormat() const override { return kPNG_SkEncodedF
ormat; } | 54 SkEncodedFormat onGetEncodedFormat() const override { return kPNG_SkEncodedF
ormat; } |
45 bool onRewind() override; | 55 bool onRewind() override; |
46 uint64_t onGetFillValue(const SkImageInfo&) const override; | 56 uint64_t onGetFillValue(const SkImageInfo&) const override; |
47 | 57 |
48 // Helper to set up swizzler, color xforms, and color table. Also calls png_
read_update_info. | |
49 bool initializeXforms(const SkImageInfo& dstInfo, const Options&, SkPMColor*
colorPtr, | |
50 int* colorCount); | |
51 void initializeSwizzler(const SkImageInfo& dstInfo, const Options&); | |
52 SkSampler* getSampler(bool createIfNecessary) override; | 58 SkSampler* getSampler(bool createIfNecessary) override; |
53 void allocateStorage(const SkImageInfo& dstInfo); | 59 void applyXformRow(void* dst, const void* src); |
54 void applyXformRow(void* dst, const void* src, SkColorType, SkAlphaType, int
width); | |
55 | 60 |
56 virtual int readRows(const SkImageInfo& dstInfo, void* dst, size_t rowBytes,
int count, | 61 voidp png_ptr() { return fPng_ptr; } |
57 int startRow) = 0; | 62 voidp info_ptr() { return fInfo_ptr; } |
58 | 63 |
59 SkPngCodec(const SkEncodedInfo&, const SkImageInfo&, SkStream*, SkPngChunkRe
ader*, | 64 SkSwizzler* swizzler() { return fSwizzler; } |
60 void* png_ptr, void* info_ptr, int, int); | 65 |
| 66 // Initialize variables used by applyXformRow. |
| 67 void initializeXformAlphaAndWidth(); |
| 68 |
| 69 /** |
| 70 * Pass available input to libpng to process it. |
| 71 * |
| 72 * libpng will call any relevant callbacks installed. This will continue de
coding |
| 73 * until it reaches the end of the file, or until a callback tells libpng t
o stop. |
| 74 */ |
| 75 void processData(); |
| 76 |
| 77 #ifdef SK_GOOGLE3_PNG_HACK |
| 78 // In libpng 1.2.56, png_process_data_pause does not exist, so when we wante
d to |
| 79 // read the header, we may have read too far. In that case, we need to delet
e the |
| 80 // png_ptr and info_ptr and recreate them. This method does that (and attach
es the |
| 81 // chunk reader. |
| 82 bool rereadHeaderIfNecessary(); |
| 83 |
| 84 // This method sets up the new png_ptr/info_ptr (created in rereadHeaderIfNe
cessary) |
| 85 // the way we set up the old one the first time in AutoCleanPng.decodeBounds
's callback. |
| 86 void rereadInfoCallback(); |
| 87 #endif |
| 88 |
| 89 Result onStartIncrementalDecode(const SkImageInfo& dstInfo, void* pixels, si
ze_t rowBytes, |
| 90 const SkCodec::Options&, |
| 91 SkPMColor* ctable, int* ctableCount) override; |
| 92 Result onIncrementalDecode(int*) override; |
61 | 93 |
62 SkAutoTUnref<SkPngChunkReader> fPngChunkReader; | 94 SkAutoTUnref<SkPngChunkReader> fPngChunkReader; |
63 voidp fPng_ptr; | 95 voidp fPng_ptr; |
64 voidp fInfo_ptr; | 96 voidp fInfo_ptr; |
65 | 97 |
66 // These are stored here so they can be used both by normal decoding and sca
nline decoding. | 98 // These are stored here so they can be used both by normal decoding and sca
nline decoding. |
67 SkAutoTUnref<SkColorTable> fColorTable; // May be unpremul. | 99 SkAutoTUnref<SkColorTable> fColorTable; // May be unpremul. |
68 SkAutoTDelete<SkSwizzler> fSwizzler; | 100 SkAutoTDelete<SkSwizzler> fSwizzler; |
69 std::unique_ptr<SkColorSpaceXform> fColorXform; | 101 std::unique_ptr<SkColorSpaceXform> fColorXform; |
70 SkAutoTMalloc<uint8_t> fStorage; | 102 SkAutoTMalloc<uint8_t> fStorage; |
71 uint8_t* fSwizzlerSrcRow; | |
72 uint32_t* fColorXformSrcRow; | 103 uint32_t* fColorXformSrcRow; |
73 size_t fSrcRowBytes; | 104 const int fBitDepth; |
74 | |
75 const int fNumberPasses; | |
76 int fBitDepth; | |
77 | 105 |
78 private: | 106 private: |
79 | 107 |
80 enum XformMode { | 108 enum XformMode { |
81 // Requires only a swizzle pass. | 109 // Requires only a swizzle pass. |
82 kSwizzleOnly_XformMode, | 110 kSwizzleOnly_XformMode, |
83 | 111 |
84 // Requires only a color xform pass. | 112 // Requires only a color xform pass. |
85 kColorOnly_XformMode, | 113 kColorOnly_XformMode, |
86 | 114 |
87 // Requires a swizzle and a color xform. | 115 // Requires a swizzle and a color xform. |
88 kSwizzleColor_XformMode, | 116 kSwizzleColor_XformMode, |
89 }; | 117 }; |
90 | 118 |
91 bool createColorTable(const SkImageInfo& dstInfo, int* ctableCount); | 119 bool createColorTable(const SkImageInfo& dstInfo, int* ctableCount); |
| 120 // Helper to set up swizzler, color xforms, and color table. Also calls png_
read_update_info. |
| 121 bool initializeXforms(const SkImageInfo& dstInfo, const Options&, SkPMColor*
colorPtr, |
| 122 int* colorCount); |
| 123 void initializeSwizzler(const SkImageInfo& dstInfo, const Options&); |
| 124 void allocateStorage(const SkImageInfo& dstInfo); |
92 void destroyReadStruct(); | 125 void destroyReadStruct(); |
93 | 126 |
94 XformMode fXformMode; | 127 virtual Result decodeAllRows(void* dst, size_t rowBytes, int* rowsDecoded) =
0; |
| 128 virtual void setRange(int firstRow, int lastRow, void* dst, size_t rowBytes)
= 0; |
| 129 virtual Result decode(int* rowsDecoded) = 0; |
| 130 |
| 131 XformMode fXformMode; |
| 132 SkAlphaType fXformAlphaType; |
| 133 int fXformWidth; |
| 134 |
| 135 #ifdef SK_GOOGLE3_PNG_HACK |
| 136 bool fNeedsToRereadHeader; |
| 137 #endif |
95 | 138 |
96 typedef SkCodec INHERITED; | 139 typedef SkCodec INHERITED; |
97 }; | 140 }; |
OLD | NEW |