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 "SkBmpCodec.h" | 8 #include "SkBmpCodec.h" |
9 #include "SkCodecPriv.h" | 9 #include "SkCodecPriv.h" |
10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
179 | 179 |
180 /* | 180 /* |
181 * Creates an instance of the decoder | 181 * Creates an instance of the decoder |
182 * Called only by NewFromStream | 182 * Called only by NewFromStream |
183 */ | 183 */ |
184 SkIcoCodec::SkIcoCodec(int width, int height, const SkEncodedInfo& info, | 184 SkIcoCodec::SkIcoCodec(int width, int height, const SkEncodedInfo& info, |
185 SkTArray<SkAutoTDelete<SkCodec>, true>* codecs) | 185 SkTArray<SkAutoTDelete<SkCodec>, true>* codecs) |
186 : INHERITED(width, height, info, nullptr) | 186 : INHERITED(width, height, info, nullptr) |
187 , fEmbeddedCodecs(codecs) | 187 , fEmbeddedCodecs(codecs) |
188 , fCurrScanlineCodec(nullptr) | 188 , fCurrScanlineCodec(nullptr) |
189 , fCurrIncrementalCodec(nullptr) | |
189 {} | 190 {} |
190 | 191 |
191 /* | 192 /* |
192 * Chooses the best dimensions given the desired scale | 193 * Chooses the best dimensions given the desired scale |
193 */ | 194 */ |
194 SkISize SkIcoCodec::onGetScaledDimensions(float desiredScale) const { | 195 SkISize SkIcoCodec::onGetScaledDimensions(float desiredScale) const { |
195 // We set the dimensions to the largest candidate image by default. | 196 // We set the dimensions to the largest candidate image by default. |
196 // Regardless of the scale request, this is the largest image that we | 197 // Regardless of the scale request, this is the largest image that we |
197 // will decode. | 198 // will decode. |
198 int origWidth = this->getInfo().width(); | 199 int origWidth = this->getInfo().width(); |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
282 while (true) { | 283 while (true) { |
283 index = this->chooseCodec(dstInfo.dimensions(), index); | 284 index = this->chooseCodec(dstInfo.dimensions(), index); |
284 if (index < 0) { | 285 if (index < 0) { |
285 break; | 286 break; |
286 } | 287 } |
287 | 288 |
288 SkCodec* embeddedCodec = fEmbeddedCodecs->operator[](index); | 289 SkCodec* embeddedCodec = fEmbeddedCodecs->operator[](index); |
289 result = embeddedCodec->startScanlineDecode(dstInfo, &options, colorTabl e, colorCount); | 290 result = embeddedCodec->startScanlineDecode(dstInfo, &options, colorTabl e, colorCount); |
290 if (kSuccess == result) { | 291 if (kSuccess == result) { |
291 fCurrScanlineCodec = embeddedCodec; | 292 fCurrScanlineCodec = embeddedCodec; |
293 fCurrIncrementalCodec = nullptr; | |
292 return result; | 294 return result; |
293 } | 295 } |
294 | 296 |
295 index++; | 297 index++; |
296 } | 298 } |
297 | 299 |
298 SkCodecPrintf("Error: No matching candidate image in ico.\n"); | 300 SkCodecPrintf("Error: No matching candidate image in ico.\n"); |
299 return result; | 301 return result; |
300 } | 302 } |
301 | 303 |
302 int SkIcoCodec::onGetScanlines(void* dst, int count, size_t rowBytes) { | 304 int SkIcoCodec::onGetScanlines(void* dst, int count, size_t rowBytes) { |
303 SkASSERT(fCurrScanlineCodec); | 305 SkASSERT(fCurrScanlineCodec); |
304 return fCurrScanlineCodec->getScanlines(dst, count, rowBytes); | 306 return fCurrScanlineCodec->getScanlines(dst, count, rowBytes); |
305 } | 307 } |
306 | 308 |
307 bool SkIcoCodec::onSkipScanlines(int count) { | 309 bool SkIcoCodec::onSkipScanlines(int count) { |
308 SkASSERT(fCurrScanlineCodec); | 310 SkASSERT(fCurrScanlineCodec); |
309 return fCurrScanlineCodec->skipScanlines(count); | 311 return fCurrScanlineCodec->skipScanlines(count); |
310 } | 312 } |
311 | 313 |
314 SkCodec::Result SkIcoCodec::onStartIncrementalDecode(const SkImageInfo& dstInfo, | |
315 void* pixels, size_t rowBytes, const SkCodec::Options& options, | |
316 SkPMColor* colorTable, int* colorCount) { | |
317 int index = 0; | |
318 while (true) { | |
319 index = this->chooseCodec(dstInfo.dimensions(), index); | |
320 if (index < 0) { | |
321 break; | |
322 } | |
323 | |
324 SkCodec* embeddedCodec = fEmbeddedCodecs->operator[](index); | |
325 switch (embeddedCodec->startIncrementalDecode(dstInfo, | |
326 pixels, rowBytes, &options, colorTable, colorCount)) { | |
327 case kSuccess: | |
328 fCurrIncrementalCodec = embeddedCodec; | |
329 fCurrScanlineCodec = nullptr; | |
330 return kSuccess; | |
331 case kUnimplemented: | |
332 // FIXME: embeddedCodec is a BMP. If scanline decoding would wor k, | |
333 // return kUnimplemented so that SkSampledCodec will fall throug h | |
334 // to use the scanline decoder. | |
335 // Note that calling startScanlineDecode will require an extra | |
336 // rewind. The embedded codec has an SkMemoryStream, which is | |
337 // cheap to rewind, though it will do extra work re-reading the | |
338 // header. | |
339 // Also note that we pass nullptr for Options. This is because | |
340 // Options that are valid for incremental decoding may not be | |
341 // valid for scanline decoding. | |
342 // Once BMP supports incremental decoding this workaround can go | |
343 // away. | |
344 if (embeddedCodec->startScanlineDecode(dstInfo, nullptr, | |
scroggo
2016/05/26 16:10:58
In patch set 9, I just called dimensionsSupported(
msarett
2016/05/26 16:45:22
Acknowledged.
| |
345 colorTable, colorCount) == kSuccess) { | |
346 return kUnimplemented; | |
347 } | |
348 // Move on to the next embedded codec. | |
349 break; | |
350 default: | |
351 break; | |
352 } | |
353 | |
354 index++; | |
355 } | |
356 | |
357 SkCodecPrintf("Error: No matching candidate image in ico.\n"); | |
358 return kInvalidScale; | |
359 } | |
360 | |
361 SkCodec::Result SkIcoCodec::onIncrementalDecode(int* rowsDecoded) { | |
362 SkASSERT(fCurrIncrementalCodec); | |
363 return fCurrIncrementalCodec->incrementalDecode(rowsDecoded); | |
364 } | |
365 | |
312 SkCodec::SkScanlineOrder SkIcoCodec::onGetScanlineOrder() const { | 366 SkCodec::SkScanlineOrder SkIcoCodec::onGetScanlineOrder() const { |
313 // FIXME: This function will possibly return the wrong value if it is called | 367 // FIXME: This function will possibly return the wrong value if it is called |
314 // before startScanlineDecode(). | 368 // before startScanlineDecode()/startIncrementalDecode(). |
315 return fCurrScanlineCodec ? fCurrScanlineCodec->getScanlineOrder() : | 369 if (fCurrScanlineCodec) { |
316 INHERITED::onGetScanlineOrder(); | 370 SkASSERT(!fCurrIncrementalCodec); |
371 return fCurrScanlineCodec->getScanlineOrder(); | |
372 } | |
373 | |
374 if (fCurrIncrementalCodec) { | |
375 return fCurrIncrementalCodec->getScanlineOrder(); | |
376 } | |
377 | |
378 return INHERITED::onGetScanlineOrder(); | |
317 } | 379 } |
318 | 380 |
319 SkSampler* SkIcoCodec::getSampler(bool createIfNecessary) { | 381 SkSampler* SkIcoCodec::getSampler(bool createIfNecessary) { |
320 return fCurrScanlineCodec ? fCurrScanlineCodec->getSampler(createIfNecessary ) : nullptr; | 382 if (fCurrScanlineCodec) { |
383 SkASSERT(!fCurrIncrementalCodec); | |
384 return fCurrScanlineCodec->getSampler(createIfNecessary); | |
385 } | |
386 | |
387 if (fCurrIncrementalCodec) { | |
388 return fCurrIncrementalCodec->getSampler(createIfNecessary); | |
389 } | |
390 | |
391 return nullptr; | |
321 } | 392 } |
OLD | NEW |