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 "SkCodecPriv.h" | 9 #include "SkCodecPriv.h" |
10 #include "SkMath.h" | 10 #include "SkMath.h" |
11 #include "SkSampledCodec.h" | 11 #include "SkSampledCodec.h" |
12 | 12 |
13 SkSampledCodec::SkSampledCodec(SkCodec* codec) | 13 SkSampledCodec::SkSampledCodec(SkCodec* codec) |
14 : INHERITED(codec->getInfo()) | 14 : INHERITED(codec) |
15 , fCodec(codec) | |
16 {} | 15 {} |
17 | 16 |
18 SkISize SkSampledCodec::accountForNativeScaling(int* sampleSizePtr, int* nativeS
ampleSize) const { | 17 SkISize SkSampledCodec::accountForNativeScaling(int* sampleSizePtr, int* nativeS
ampleSize) const { |
19 SkISize preSampledSize = fCodec->getInfo().dimensions(); | 18 SkISize preSampledSize = this->codec()->getInfo().dimensions(); |
20 int sampleSize = *sampleSizePtr; | 19 int sampleSize = *sampleSizePtr; |
21 SkASSERT(sampleSize > 1); | 20 SkASSERT(sampleSize > 1); |
22 | 21 |
23 if (nativeSampleSize) { | 22 if (nativeSampleSize) { |
24 *nativeSampleSize = 1; | 23 *nativeSampleSize = 1; |
25 } | 24 } |
26 | 25 |
27 // Only JPEG supports native downsampling. | 26 // Only JPEG supports native downsampling. |
28 if (fCodec->getEncodedFormat() == kJPEG_SkEncodedFormat) { | 27 if (this->codec()->getEncodedFormat() == kJPEG_SkEncodedFormat) { |
29 // See if libjpeg supports this scale directly | 28 // See if libjpeg supports this scale directly |
30 switch (sampleSize) { | 29 switch (sampleSize) { |
31 case 2: | 30 case 2: |
32 case 4: | 31 case 4: |
33 case 8: | 32 case 8: |
34 // This class does not need to do any sampling. | 33 // This class does not need to do any sampling. |
35 *sampleSizePtr = 1; | 34 *sampleSizePtr = 1; |
36 return fCodec->getScaledDimensions(get_scale_from_sample_size(sa
mpleSize)); | 35 return this->codec()->getScaledDimensions(get_scale_from_sample_
size(sampleSize)); |
37 default: | 36 default: |
38 break; | 37 break; |
39 } | 38 } |
40 | 39 |
41 // Check if sampleSize is a multiple of something libjpeg can support. | 40 // Check if sampleSize is a multiple of something libjpeg can support. |
42 int remainder; | 41 int remainder; |
43 const int sampleSizes[] = { 8, 4, 2 }; | 42 const int sampleSizes[] = { 8, 4, 2 }; |
44 for (int supportedSampleSize : sampleSizes) { | 43 for (int supportedSampleSize : sampleSizes) { |
45 int actualSampleSize; | 44 int actualSampleSize; |
46 SkTDivMod(sampleSize, supportedSampleSize, &actualSampleSize, &remai
nder); | 45 SkTDivMod(sampleSize, supportedSampleSize, &actualSampleSize, &remai
nder); |
47 if (0 == remainder) { | 46 if (0 == remainder) { |
48 float scale = get_scale_from_sample_size(supportedSampleSize); | 47 float scale = get_scale_from_sample_size(supportedSampleSize); |
49 | 48 |
50 // fCodec will scale to this size. | 49 // this->codec() will scale to this size. |
51 preSampledSize = fCodec->getScaledDimensions(scale); | 50 preSampledSize = this->codec()->getScaledDimensions(scale); |
52 | 51 |
53 // And then this class will sample it. | 52 // And then this class will sample it. |
54 *sampleSizePtr = actualSampleSize; | 53 *sampleSizePtr = actualSampleSize; |
55 if (nativeSampleSize) { | 54 if (nativeSampleSize) { |
56 *nativeSampleSize = supportedSampleSize; | 55 *nativeSampleSize = supportedSampleSize; |
57 } | 56 } |
58 break; | 57 break; |
59 } | 58 } |
60 } | 59 } |
61 } | 60 } |
62 | 61 |
63 return preSampledSize; | 62 return preSampledSize; |
64 } | 63 } |
65 | 64 |
66 SkISize SkSampledCodec::onGetSampledDimensions(int sampleSize) const { | 65 SkISize SkSampledCodec::onGetSampledDimensions(int sampleSize) const { |
67 const SkISize size = this->accountForNativeScaling(&sampleSize); | 66 const SkISize size = this->accountForNativeScaling(&sampleSize); |
68 return SkISize::Make(get_scaled_dimension(size.width(), sampleSize), | 67 return SkISize::Make(get_scaled_dimension(size.width(), sampleSize), |
69 get_scaled_dimension(size.height(), sampleSize)); | 68 get_scaled_dimension(size.height(), sampleSize)); |
70 } | 69 } |
71 | 70 |
72 SkCodec::Result SkSampledCodec::onGetAndroidPixels(const SkImageInfo& info, void
* pixels, | 71 SkCodec::Result SkSampledCodec::onGetAndroidPixels(const SkImageInfo& info, void
* pixels, |
73 size_t rowBytes, const AndroidOptions& options) { | 72 size_t rowBytes, const AndroidOptions& options) { |
74 // Create an Options struct for the codec. | 73 // Create an Options struct for the codec. |
75 SkCodec::Options codecOptions; | 74 SkCodec::Options codecOptions; |
76 codecOptions.fZeroInitialized = options.fZeroInitialized; | 75 codecOptions.fZeroInitialized = options.fZeroInitialized; |
77 | 76 |
78 SkIRect* subset = options.fSubset; | 77 SkIRect* subset = options.fSubset; |
79 if (!subset || subset->size() == fCodec->getInfo().dimensions()) { | 78 if (!subset || subset->size() == this->codec()->getInfo().dimensions()) { |
80 if (fCodec->dimensionsSupported(info.dimensions())) { | 79 if (this->codec()->dimensionsSupported(info.dimensions())) { |
81 return fCodec->getPixels(info, pixels, rowBytes, &codecOptions, opti
ons.fColorPtr, | 80 return this->codec()->getPixels(info, pixels, rowBytes, &codecOption
s, |
82 options.fColorCount); | 81 options.fColorPtr, options.fColorCount); |
83 } | 82 } |
84 | 83 |
85 // If the native codec does not support the requested scale, scale by sa
mpling. | 84 // If the native codec does not support the requested scale, scale by sa
mpling. |
86 return this->sampledDecode(info, pixels, rowBytes, options); | 85 return this->sampledDecode(info, pixels, rowBytes, options); |
87 } | 86 } |
88 | 87 |
89 // We are performing a subset decode. | 88 // We are performing a subset decode. |
90 int sampleSize = options.fSampleSize; | 89 int sampleSize = options.fSampleSize; |
91 SkISize scaledSize = this->getSampledDimensions(sampleSize); | 90 SkISize scaledSize = this->getSampledDimensions(sampleSize); |
92 if (!fCodec->dimensionsSupported(scaledSize)) { | 91 if (!this->codec()->dimensionsSupported(scaledSize)) { |
93 // If the native codec does not support the requested scale, scale by sa
mpling. | 92 // If the native codec does not support the requested scale, scale by sa
mpling. |
94 return this->sampledDecode(info, pixels, rowBytes, options); | 93 return this->sampledDecode(info, pixels, rowBytes, options); |
95 } | 94 } |
96 | 95 |
97 // Calculate the scaled subset bounds. | 96 // Calculate the scaled subset bounds. |
98 int scaledSubsetX = subset->x() / sampleSize; | 97 int scaledSubsetX = subset->x() / sampleSize; |
99 int scaledSubsetY = subset->y() / sampleSize; | 98 int scaledSubsetY = subset->y() / sampleSize; |
100 int scaledSubsetWidth = info.width(); | 99 int scaledSubsetWidth = info.width(); |
101 int scaledSubsetHeight = info.height(); | 100 int scaledSubsetHeight = info.height(); |
102 | 101 |
103 // Start the scanline decode. | 102 // Start the scanline decode. |
104 SkIRect scanlineSubset = SkIRect::MakeXYWH(scaledSubsetX, 0, scaledSubsetWid
th, | 103 SkIRect scanlineSubset = SkIRect::MakeXYWH(scaledSubsetX, 0, scaledSubsetWid
th, |
105 scaledSize.height()); | 104 scaledSize.height()); |
106 codecOptions.fSubset = &scanlineSubset; | 105 codecOptions.fSubset = &scanlineSubset; |
107 SkCodec::Result result = fCodec->startScanlineDecode(info.makeWH(scaledSize.
width(), | 106 SkCodec::Result result = this->codec()->startScanlineDecode(info.makeWH(scal
edSize.width(), |
108 scaledSize.height()), &codecOptions, options.fColorPtr, options.fCol
orCount); | 107 scaledSize.height()), &codecOptions, options.fColorPtr, options.fCol
orCount); |
109 if (SkCodec::kSuccess != result) { | 108 if (SkCodec::kSuccess != result) { |
110 return result; | 109 return result; |
111 } | 110 } |
112 | 111 |
113 // At this point, we are only concerned with subsetting. Either no scale wa
s | 112 // At this point, we are only concerned with subsetting. Either no scale wa
s |
114 // requested, or the fCodec is handling the scale. | 113 // requested, or the this->codec() is handling the scale. |
115 switch (fCodec->getScanlineOrder()) { | 114 switch (this->codec()->getScanlineOrder()) { |
116 case SkCodec::kTopDown_SkScanlineOrder: | 115 case SkCodec::kTopDown_SkScanlineOrder: |
117 case SkCodec::kNone_SkScanlineOrder: { | 116 case SkCodec::kNone_SkScanlineOrder: { |
118 if (!fCodec->skipScanlines(scaledSubsetY)) { | 117 if (!this->codec()->skipScanlines(scaledSubsetY)) { |
119 fCodec->fillIncompleteImage(info, pixels, rowBytes, options.fZer
oInitialized, | 118 this->codec()->fillIncompleteImage(info, pixels, rowBytes, optio
ns.fZeroInitialized, |
120 scaledSubsetHeight, 0); | 119 scaledSubsetHeight, 0); |
121 return SkCodec::kIncompleteInput; | 120 return SkCodec::kIncompleteInput; |
122 } | 121 } |
123 | 122 |
124 int decodedLines = fCodec->getScanlines(pixels, scaledSubsetHeight,
rowBytes); | 123 int decodedLines = this->codec()->getScanlines(pixels, scaledSubsetH
eight, rowBytes); |
125 if (decodedLines != scaledSubsetHeight) { | 124 if (decodedLines != scaledSubsetHeight) { |
126 return SkCodec::kIncompleteInput; | 125 return SkCodec::kIncompleteInput; |
127 } | 126 } |
128 return SkCodec::kSuccess; | 127 return SkCodec::kSuccess; |
129 } | 128 } |
130 default: | 129 default: |
131 SkASSERT(false); | 130 SkASSERT(false); |
132 return SkCodec::kUnimplemented; | 131 return SkCodec::kUnimplemented; |
133 } | 132 } |
134 } | 133 } |
(...skipping 14 matching lines...) Expand all Loading... |
149 SkISize nativeSize = this->accountForNativeScaling(&sampleSize, &nativeSampl
eSize); | 148 SkISize nativeSize = this->accountForNativeScaling(&sampleSize, &nativeSampl
eSize); |
150 | 149 |
151 // Check if there is a subset. | 150 // Check if there is a subset. |
152 SkIRect subset; | 151 SkIRect subset; |
153 int subsetY = 0; | 152 int subsetY = 0; |
154 int subsetWidth = nativeSize.width(); | 153 int subsetWidth = nativeSize.width(); |
155 int subsetHeight = nativeSize.height(); | 154 int subsetHeight = nativeSize.height(); |
156 if (options.fSubset) { | 155 if (options.fSubset) { |
157 // We will need to know about subsetting in the y-dimension in order to
use the | 156 // We will need to know about subsetting in the y-dimension in order to
use the |
158 // scanline decoder. | 157 // scanline decoder. |
159 // Update the subset to account for scaling done by fCodec. | 158 // Update the subset to account for scaling done by this->codec(). |
160 SkIRect* subsetPtr = options.fSubset; | 159 SkIRect* subsetPtr = options.fSubset; |
161 | 160 |
162 // Do the divide ourselves, instead of calling get_scaled_dimension. If | 161 // Do the divide ourselves, instead of calling get_scaled_dimension. If |
163 // X and Y are 0, they should remain 0, rather than being upgraded to 1 | 162 // X and Y are 0, they should remain 0, rather than being upgraded to 1 |
164 // due to being smaller than the sampleSize. | 163 // due to being smaller than the sampleSize. |
165 const int subsetX = subsetPtr->x() / nativeSampleSize; | 164 const int subsetX = subsetPtr->x() / nativeSampleSize; |
166 subsetY = subsetPtr->y() / nativeSampleSize; | 165 subsetY = subsetPtr->y() / nativeSampleSize; |
167 | 166 |
168 subsetWidth = get_scaled_dimension(subsetPtr->width(), nativeSampleSize)
; | 167 subsetWidth = get_scaled_dimension(subsetPtr->width(), nativeSampleSize)
; |
169 subsetHeight = get_scaled_dimension(subsetPtr->height(), nativeSampleSiz
e); | 168 subsetHeight = get_scaled_dimension(subsetPtr->height(), nativeSampleSiz
e); |
170 | 169 |
171 // The scanline decoder only needs to be aware of subsetting in the x-di
mension. | 170 // The scanline decoder only needs to be aware of subsetting in the x-di
mension. |
172 subset.setXYWH(subsetX, 0, subsetWidth, nativeSize.height()); | 171 subset.setXYWH(subsetX, 0, subsetWidth, nativeSize.height()); |
173 sampledOptions.fSubset = ⊂ | 172 sampledOptions.fSubset = ⊂ |
174 } | 173 } |
175 | 174 |
176 // Start the scanline decode. | 175 // Start the scanline decode. |
177 SkCodec::Result result = fCodec->startScanlineDecode( | 176 SkCodec::Result result = this->codec()->startScanlineDecode( |
178 info.makeWH(nativeSize.width(), nativeSize.height()), &sampledOption
s, | 177 info.makeWH(nativeSize.width(), nativeSize.height()), &sampledOption
s, |
179 options.fColorPtr, options.fColorCount); | 178 options.fColorPtr, options.fColorCount); |
180 if (SkCodec::kSuccess != result) { | 179 if (SkCodec::kSuccess != result) { |
181 return result; | 180 return result; |
182 } | 181 } |
183 | 182 |
184 SkSampler* sampler = fCodec->getSampler(true); | 183 SkSampler* sampler = this->codec()->getSampler(true); |
185 if (!sampler) { | 184 if (!sampler) { |
186 return SkCodec::kUnimplemented; | 185 return SkCodec::kUnimplemented; |
187 } | 186 } |
188 | 187 |
189 // Since we guarantee that output dimensions are always at least one (even i
f the sampleSize | 188 // Since we guarantee that output dimensions are always at least one (even i
f the sampleSize |
190 // is greater than a given dimension), the input sampleSize is not always th
e sampleSize that | 189 // is greater than a given dimension), the input sampleSize is not always th
e sampleSize that |
191 // we use in practice. | 190 // we use in practice. |
192 const int sampleX = subsetWidth / info.width(); | 191 const int sampleX = subsetWidth / info.width(); |
193 const int sampleY = subsetHeight / info.height(); | 192 const int sampleY = subsetHeight / info.height(); |
194 if (sampler->setSampleX(sampleX) != info.width()) { | 193 if (sampler->setSampleX(sampleX) != info.width()) { |
195 return SkCodec::kInvalidScale; | 194 return SkCodec::kInvalidScale; |
196 } | 195 } |
197 if (get_scaled_dimension(subsetHeight, sampleY) != info.height()) { | 196 if (get_scaled_dimension(subsetHeight, sampleY) != info.height()) { |
198 return SkCodec::kInvalidScale; | 197 return SkCodec::kInvalidScale; |
199 } | 198 } |
200 | 199 |
201 const int samplingOffsetY = get_start_coord(sampleY); | 200 const int samplingOffsetY = get_start_coord(sampleY); |
202 const int startY = samplingOffsetY + subsetY; | 201 const int startY = samplingOffsetY + subsetY; |
203 int dstHeight = info.height(); | 202 int dstHeight = info.height(); |
204 switch(fCodec->getScanlineOrder()) { | 203 switch(this->codec()->getScanlineOrder()) { |
205 case SkCodec::kTopDown_SkScanlineOrder: { | 204 case SkCodec::kTopDown_SkScanlineOrder: { |
206 if (!fCodec->skipScanlines(startY)) { | 205 if (!this->codec()->skipScanlines(startY)) { |
207 fCodec->fillIncompleteImage(info, pixels, rowBytes, options.fZer
oInitialized, | 206 this->codec()->fillIncompleteImage(info, pixels, rowBytes, optio
ns.fZeroInitialized, |
208 dstHeight, 0); | 207 dstHeight, 0); |
209 return SkCodec::kIncompleteInput; | 208 return SkCodec::kIncompleteInput; |
210 } | 209 } |
211 void* pixelPtr = pixels; | 210 void* pixelPtr = pixels; |
212 for (int y = 0; y < dstHeight; y++) { | 211 for (int y = 0; y < dstHeight; y++) { |
213 if (1 != fCodec->getScanlines(pixelPtr, 1, rowBytes)) { | 212 if (1 != this->codec()->getScanlines(pixelPtr, 1, rowBytes)) { |
214 fCodec->fillIncompleteImage(info, pixels, rowBytes, options.
fZeroInitialized, | 213 this->codec()->fillIncompleteImage(info, pixels, rowBytes, |
215 dstHeight, y + 1); | 214 options.fZeroInitialized, dstHeight, y + 1); |
216 return SkCodec::kIncompleteInput; | 215 return SkCodec::kIncompleteInput; |
217 } | 216 } |
218 if (y < dstHeight - 1) { | 217 if (y < dstHeight - 1) { |
219 if (!fCodec->skipScanlines(sampleY - 1)) { | 218 if (!this->codec()->skipScanlines(sampleY - 1)) { |
220 fCodec->fillIncompleteImage(info, pixels, rowBytes, | 219 this->codec()->fillIncompleteImage(info, pixels, rowByte
s, |
221 options.fZeroInitialized, dstHeight, y + 1); | 220 options.fZeroInitialized, dstHeight, y + 1); |
222 return SkCodec::kIncompleteInput; | 221 return SkCodec::kIncompleteInput; |
223 } | 222 } |
224 } | 223 } |
225 pixelPtr = SkTAddOffset<void>(pixelPtr, rowBytes); | 224 pixelPtr = SkTAddOffset<void>(pixelPtr, rowBytes); |
226 } | 225 } |
227 return SkCodec::kSuccess; | 226 return SkCodec::kSuccess; |
228 } | 227 } |
229 case SkCodec::kOutOfOrder_SkScanlineOrder: | 228 case SkCodec::kOutOfOrder_SkScanlineOrder: |
230 case SkCodec::kBottomUp_SkScanlineOrder: { | 229 case SkCodec::kBottomUp_SkScanlineOrder: { |
231 // Note that these modes do not support subsetting. | 230 // Note that these modes do not support subsetting. |
232 SkASSERT(0 == subsetY && nativeSize.height() == subsetHeight); | 231 SkASSERT(0 == subsetY && nativeSize.height() == subsetHeight); |
233 int y; | 232 int y; |
234 for (y = 0; y < nativeSize.height(); y++) { | 233 for (y = 0; y < nativeSize.height(); y++) { |
235 int srcY = fCodec->nextScanline(); | 234 int srcY = this->codec()->nextScanline(); |
236 if (is_coord_necessary(srcY, sampleY, dstHeight)) { | 235 if (is_coord_necessary(srcY, sampleY, dstHeight)) { |
237 void* pixelPtr = SkTAddOffset<void>(pixels, | 236 void* pixelPtr = SkTAddOffset<void>(pixels, |
238 rowBytes * get_dst_coord(srcY, sampleY)); | 237 rowBytes * get_dst_coord(srcY, sampleY)); |
239 if (1 != fCodec->getScanlines(pixelPtr, 1, rowBytes)) { | 238 if (1 != this->codec()->getScanlines(pixelPtr, 1, rowBytes))
{ |
240 break; | 239 break; |
241 } | 240 } |
242 } else { | 241 } else { |
243 if (!fCodec->skipScanlines(1)) { | 242 if (!this->codec()->skipScanlines(1)) { |
244 break; | 243 break; |
245 } | 244 } |
246 } | 245 } |
247 } | 246 } |
248 | 247 |
249 if (nativeSize.height() == y) { | 248 if (nativeSize.height() == y) { |
250 return SkCodec::kSuccess; | 249 return SkCodec::kSuccess; |
251 } | 250 } |
252 | 251 |
253 // We handle filling uninitialized memory here instead of using fCod
ec. | 252 // We handle filling uninitialized memory here instead of using this
->codec(). |
254 // fCodec does not know that we are sampling. | 253 // this->codec() does not know that we are sampling. |
255 const uint32_t fillValue = fCodec->getFillValue(info.colorType(), in
fo.alphaType()); | 254 const uint32_t fillValue = this->codec()->getFillValue(info.colorTyp
e(), |
| 255 info.alphaType()); |
256 const SkImageInfo fillInfo = info.makeWH(info.width(), 1); | 256 const SkImageInfo fillInfo = info.makeWH(info.width(), 1); |
257 for (; y < nativeSize.height(); y++) { | 257 for (; y < nativeSize.height(); y++) { |
258 int srcY = fCodec->outputScanline(y); | 258 int srcY = this->codec()->outputScanline(y); |
259 if (!is_coord_necessary(srcY, sampleY, dstHeight)) { | 259 if (!is_coord_necessary(srcY, sampleY, dstHeight)) { |
260 continue; | 260 continue; |
261 } | 261 } |
262 | 262 |
263 void* rowPtr = SkTAddOffset<void>(pixels, rowBytes * get_dst_coo
rd(srcY, sampleY)); | 263 void* rowPtr = SkTAddOffset<void>(pixels, rowBytes * get_dst_coo
rd(srcY, sampleY)); |
264 SkSampler::Fill(fillInfo, rowPtr, rowBytes, fillValue, options.f
ZeroInitialized); | 264 SkSampler::Fill(fillInfo, rowPtr, rowBytes, fillValue, options.f
ZeroInitialized); |
265 } | 265 } |
266 return SkCodec::kIncompleteInput; | 266 return SkCodec::kIncompleteInput; |
267 } | 267 } |
268 case SkCodec::kNone_SkScanlineOrder: { | 268 case SkCodec::kNone_SkScanlineOrder: { |
269 const int linesNeeded = subsetHeight - samplingOffsetY; | 269 const int linesNeeded = subsetHeight - samplingOffsetY; |
270 SkAutoMalloc storage(linesNeeded * rowBytes); | 270 SkAutoMalloc storage(linesNeeded * rowBytes); |
271 uint8_t* storagePtr = static_cast<uint8_t*>(storage.get()); | 271 uint8_t* storagePtr = static_cast<uint8_t*>(storage.get()); |
272 | 272 |
273 if (!fCodec->skipScanlines(startY)) { | 273 if (!this->codec()->skipScanlines(startY)) { |
274 fCodec->fillIncompleteImage(info, pixels, rowBytes, options.fZer
oInitialized, | 274 this->codec()->fillIncompleteImage(info, pixels, rowBytes, optio
ns.fZeroInitialized, |
275 dstHeight, 0); | 275 dstHeight, 0); |
276 return SkCodec::kIncompleteInput; | 276 return SkCodec::kIncompleteInput; |
277 } | 277 } |
278 int scanlines = fCodec->getScanlines(storagePtr, linesNeeded, rowByt
es); | 278 int scanlines = this->codec()->getScanlines(storagePtr, linesNeeded,
rowBytes); |
279 | 279 |
280 for (int y = 0; y < dstHeight; y++) { | 280 for (int y = 0; y < dstHeight; y++) { |
281 memcpy(pixels, storagePtr, info.minRowBytes()); | 281 memcpy(pixels, storagePtr, info.minRowBytes()); |
282 storagePtr += sampleY * rowBytes; | 282 storagePtr += sampleY * rowBytes; |
283 pixels = SkTAddOffset<void>(pixels, rowBytes); | 283 pixels = SkTAddOffset<void>(pixels, rowBytes); |
284 } | 284 } |
285 | 285 |
286 if (scanlines < dstHeight) { | 286 if (scanlines < dstHeight) { |
287 // fCodec has already handled filling uninitialized memory. | 287 // this->codec() has already handled filling uninitialized memor
y. |
288 return SkCodec::kIncompleteInput; | 288 return SkCodec::kIncompleteInput; |
289 } | 289 } |
290 return SkCodec::kSuccess; | 290 return SkCodec::kSuccess; |
291 } | 291 } |
292 default: | 292 default: |
293 SkASSERT(false); | 293 SkASSERT(false); |
294 return SkCodec::kUnimplemented; | 294 return SkCodec::kUnimplemented; |
295 } | 295 } |
296 } | 296 } |
OLD | NEW |