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