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 |