Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(244)

Side by Side Diff: include/codec/SkScanlineDecoder.h

Issue 1267583002: Create a scanline decoder without creating a codec (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fix bugs. Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 #ifndef SkScanlineDecoder_DEFINED 8 #ifndef SkScanlineDecoder_DEFINED
9 #define SkScanlineDecoder_DEFINED 9 #define SkScanlineDecoder_DEFINED
10 10
11 #include "SkTypes.h" 11 #include "SkTypes.h"
12 #include "SkCodec.h" 12 #include "SkCodec.h"
13 #include "SkTemplates.h" 13 #include "SkTemplates.h"
14 #include "SkImageInfo.h" 14 #include "SkImageInfo.h"
15 15
16 class SkScanlineDecoder : public SkNoncopyable { 16 class SkScanlineDecoder : public SkNoncopyable {
17 public: 17 public:
18 /** 18 /**
19 * If this stream represents an encoded image that we know how to decode
20 * in scanlines, return an SkScanlineDecoder that can decode it. Otherwise
21 * return NULL.
22 *
23 * reset must be called in order to decode any scanlines.
24 *
25 * If NULL is returned, the stream is deleted immediately. Otherwise, the
26 * SkScanlineDecoder takes ownership of it, and will delete it when done
27 * with it.
28 */
29 static SkScanlineDecoder* NewFromStream(SkStream*);
30
31 /**
32 * Similar to NewFromStream, but reads from an SkData.
33 *
34 * Will take a ref if it returns a scanline decoder, else will not affect
35 * the data.
36 */
37 static SkScanlineDecoder* NewFromData(SkData*);
38
39 /**
19 * Clean up after reading/skipping scanlines. 40 * Clean up after reading/skipping scanlines.
20 * 41 *
21 * It is possible that not all scanlines will have been read/skipped. In 42 * It is possible that not all scanlines will have been read/skipped. In
22 * fact, in the case of subset decodes, it is likely that there will be 43 * fact, in the case of subset decodes, it is likely that there will be
23 * scanlines at the bottom of the image that have been ignored. 44 * scanlines at the bottom of the image that have been ignored.
24 */ 45 */
25 virtual ~SkScanlineDecoder() {} 46 virtual ~SkScanlineDecoder() {}
26 47
27 /** 48 /**
49 * Returns the default info, corresponding to the encoded data.
50 *
51 * If reset has never been called, this is the info that will be used.
52 */
53 const SkImageInfo& getInfo() { return fSrcInfo; }
54
55 /**
56 * Reset to the first scanline, with the specified options.
57 *
58 * This may require rewinding the stream.
59 *
60 * @param dstInfo Info of the destination. If the dimensions do not match
61 * those of getInfo, this implies a scale.
62 * @param options Contains decoding options, including if memory is zero
63 * initialized.
64 * @param ctable A pointer to a color table. When dstInfo.colorType() is
65 * kIndex8, this should be non-NULL and have enough storage for 256
66 * colors. The color table will be populated after decoding the palett e.
67 * @param ctableCount A pointer to the size of the color table. When
68 * dstInfo.colorType() is kIndex8, this should be non-NULL. It will
69 * be modified to the true size of the color table (<= 256) after
70 * decoding the palette.
71 * @return Enum representing success or reason for failure.
72 */
73 SkCodec::Result reset(const SkImageInfo& dstInfo, const SkCodec::Options* op tions,
74 SkPMColor ctable[], int* ctableCount);
75
76 /**
77 * Simplified version of reset() that asserts that info is NOT
78 * kIndex8_SkColorType and uses the default Options.
79 */
80 SkCodec::Result reset(const SkImageInfo& dstInfo);
msarett 2015/07/30 12:58:46 So can we get away with not calling reset() at all
scroggo 2015/07/30 15:11:35 Agreed. When I originally wrote the header, I made
81
82 /**
28 * Write the next countLines scanlines into dst. 83 * Write the next countLines scanlines into dst.
29 * 84 *
30 * @param dst Must be non-null, and large enough to hold countLines 85 * @param dst Must be non-null, and large enough to hold countLines
31 * scanlines of size rowBytes. 86 * scanlines of size rowBytes.
32 * @param countLines Number of lines to write. 87 * @param countLines Number of lines to write.
33 * @param rowBytes Number of bytes per row. Must be large enough to hold 88 * @param rowBytes Number of bytes per row. Must be large enough to hold
34 * a scanline based on the SkImageInfo used to create this object. 89 * a scanline based on the SkImageInfo used to create this object.
35 */ 90 */
36 SkCodec::Result getScanlines(void* dst, int countLines, size_t rowBytes) { 91 SkCodec::Result getScanlines(void* dst, int countLines, size_t rowBytes) {
92 if (fDstInfo.isEmpty()) {
msarett 2015/07/30 12:58:46 Maybe there is a way to make to this check once ra
scroggo 2015/07/30 15:11:35 Actually, what I was trying to check was that you
msarett 2015/07/30 15:37:55 +1 for using SkASSERT.
93 return SkCodec::kInvalidParameters;
94 }
37 if ((rowBytes < fDstInfo.minRowBytes() && countLines > 1 ) || countLines <= 0 95 if ((rowBytes < fDstInfo.minRowBytes() && countLines > 1 ) || countLines <= 0
38 || fCurrScanline + countLines > fDstInfo.height()) { 96 || fCurrScanline + countLines > fDstInfo.height()) {
39 return SkCodec::kInvalidParameters; 97 return SkCodec::kInvalidParameters;
40 } 98 }
41 const SkCodec::Result result = this->onGetScanlines(dst, countLines, row Bytes); 99 const SkCodec::Result result = this->onGetScanlines(dst, countLines, row Bytes);
42 fCurrScanline += countLines; 100 fCurrScanline += countLines;
43 return result; 101 return result;
44 } 102 }
45 103
46 /** 104 /**
47 * Skip count scanlines. 105 * Skip count scanlines.
48 * 106 *
49 * The default version just calls onGetScanlines and discards the dst. 107 * The default version just calls onGetScanlines and discards the dst.
50 * NOTE: If skipped lines are the only lines with alpha, this default 108 * NOTE: If skipped lines are the only lines with alpha, this default
51 * will make reallyHasAlpha return true, when it could have returned 109 * will make reallyHasAlpha return true, when it could have returned
52 * false. 110 * false.
53 */ 111 */
54 SkCodec::Result skipScanlines(int countLines) { 112 SkCodec::Result skipScanlines(int countLines) {
113 if (fDstInfo.isEmpty()) {
msarett 2015/07/30 12:58:46 Same question as getScanlines().
scroggo 2015/07/30 15:11:35 Acknowledged.
114 return SkCodec::kInvalidParameters;
115 }
55 if (fCurrScanline + countLines > fDstInfo.height()) { 116 if (fCurrScanline + countLines > fDstInfo.height()) {
56 // Arguably, we could just skip the scanlines which are remaining, 117 // Arguably, we could just skip the scanlines which are remaining,
57 // and return kSuccess. We choose to return invalid so the client 118 // and return kSuccess. We choose to return invalid so the client
58 // can catch their bug. 119 // can catch their bug.
59 return SkCodec::kInvalidParameters; 120 return SkCodec::kInvalidParameters;
60 } 121 }
61 const SkCodec::Result result = this->onSkipScanlines(countLines); 122 const SkCodec::Result result = this->onSkipScanlines(countLines);
62 fCurrScanline += countLines; 123 fCurrScanline += countLines;
63 return result; 124 return result;
64 } 125 }
65 126
66 /** 127 /**
67 * Some images may initially report that they have alpha due to the format 128 * Some images may initially report that they have alpha due to the format
68 * of the encoded data, but then never use any colors which have alpha 129 * of the encoded data, but then never use any colors which have alpha
69 * less than 100%. This function can be called *after* decoding to 130 * less than 100%. This function can be called *after* decoding to
70 * determine if such an image truly had alpha. Calling it before decoding 131 * determine if such an image truly had alpha. Calling it before decoding
71 * is undefined. 132 * is undefined.
72 * FIXME: see skbug.com/3582. 133 * FIXME: see skbug.com/3582.
73 */ 134 */
74 bool reallyHasAlpha() const { 135 bool reallyHasAlpha() const {
75 return this->onReallyHasAlpha(); 136 return this->onReallyHasAlpha();
76 } 137 }
77 138
78 protected: 139 protected:
79 SkScanlineDecoder(const SkImageInfo& requested) 140 SkScanlineDecoder(const SkImageInfo& srcInfo)
80 : fDstInfo(requested) 141 : fSrcInfo(srcInfo)
142 , fDstInfo()
81 , fCurrScanline(0) {} 143 , fCurrScanline(0) {}
82 144
83 virtual bool onReallyHasAlpha() const { return false; } 145 virtual bool onReallyHasAlpha() const { return false; }
84 146
85 const SkImageInfo& dstInfo() const { return fDstInfo; } 147 const SkImageInfo& dstInfo() const { return fDstInfo; }
86 148
87 private: 149 private:
88 const SkImageInfo fDstInfo; 150 const SkImageInfo fSrcInfo;
151 SkImageInfo fDstInfo;
89 int fCurrScanline; 152 int fCurrScanline;
90 153
154 virtual SkCodec::Result onReset(const SkImageInfo& dstInfo,
155 const SkCodec::Options& options,
156 SkPMColor ctable[], int* ctableCount) = 0;
157
91 // Naive default version just calls onGetScanlines on temp memory. 158 // Naive default version just calls onGetScanlines on temp memory.
92 virtual SkCodec::Result onSkipScanlines(int countLines) { 159 virtual SkCodec::Result onSkipScanlines(int countLines) {
93 SkAutoMalloc storage(fDstInfo.minRowBytes()); 160 SkAutoMalloc storage(fDstInfo.minRowBytes());
94 // Note that we pass 0 to rowBytes so we continue to use the same memory . 161 // Note that we pass 0 to rowBytes so we continue to use the same memory .
95 // Also note that while getScanlines checks that rowBytes is big enough, 162 // Also note that while getScanlines checks that rowBytes is big enough,
96 // onGetScanlines bypasses that check. 163 // onGetScanlines bypasses that check.
97 // Calling the virtual method also means we do not double count 164 // Calling the virtual method also means we do not double count
98 // countLines. 165 // countLines.
99 return this->onGetScanlines(storage.get(), countLines, 0); 166 return this->onGetScanlines(storage.get(), countLines, 0);
100 } 167 }
101 168
102 virtual SkCodec::Result onGetScanlines(void* dst, int countLines, 169 virtual SkCodec::Result onGetScanlines(void* dst, int countLines,
103 size_t rowBytes) = 0; 170 size_t rowBytes) = 0;
104 171
105 }; 172 };
106 #endif // SkScanlineDecoder_DEFINED 173 #endif // SkScanlineDecoder_DEFINED
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698