| 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, |
| 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 |