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_libgif.h" | 8 #include "SkCodec_libgif.h" |
9 #include "SkCodecPriv.h" | 9 #include "SkCodecPriv.h" |
10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" |
(...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
428 colorPtr[i] = colorPtr[fFillIndex]; | 428 colorPtr[i] = colorPtr[fFillIndex]; |
429 } | 429 } |
430 | 430 |
431 fColorTable.reset(new SkColorTable(colorPtr, maxColors)); | 431 fColorTable.reset(new SkColorTable(colorPtr, maxColors)); |
432 copy_color_table(dstInfo, this->fColorTable, inputColorPtr, inputColorCount)
; | 432 copy_color_table(dstInfo, this->fColorTable, inputColorPtr, inputColorCount)
; |
433 } | 433 } |
434 | 434 |
435 SkCodec::Result SkGifCodec::prepareToDecode(const SkImageInfo& dstInfo, SkPMColo
r* inputColorPtr, | 435 SkCodec::Result SkGifCodec::prepareToDecode(const SkImageInfo& dstInfo, SkPMColo
r* inputColorPtr, |
436 int* inputColorCount, const Options& opts) { | 436 int* inputColorCount, const Options& opts) { |
437 // Check for valid input parameters | 437 // Check for valid input parameters |
438 if (opts.fSubset) { | |
439 // Subsets are not supported. | |
440 return kUnimplemented; | |
441 } | |
442 if (!conversion_possible(dstInfo, this->getInfo())) { | 438 if (!conversion_possible(dstInfo, this->getInfo())) { |
443 return gif_error("Cannot convert input type to output type.\n", | 439 return gif_error("Cannot convert input type to output type.\n", |
444 kInvalidConversion); | 440 kInvalidConversion); |
445 } | 441 } |
446 | 442 |
447 // Initialize color table and copy to the client if necessary | 443 // Initialize color table and copy to the client if necessary |
448 this->initializeColorTable(dstInfo, inputColorPtr, inputColorCount); | 444 this->initializeColorTable(dstInfo, inputColorPtr, inputColorCount); |
449 return kSuccess; | 445 return kSuccess; |
450 } | 446 } |
451 | 447 |
452 SkCodec::Result SkGifCodec::initializeSwizzler(const SkImageInfo& dstInfo, | 448 SkCodec::Result SkGifCodec::initializeSwizzler(const SkImageInfo& dstInfo, const
Options& opts) { |
453 ZeroInitialized zeroInit) { | |
454 const SkPMColor* colorPtr = get_color_ptr(fColorTable.get()); | 449 const SkPMColor* colorPtr = get_color_ptr(fColorTable.get()); |
455 fSwizzler.reset(SkSwizzler::CreateSwizzler(SkSwizzler::kIndex, | 450 fSwizzler.reset(SkSwizzler::CreateSwizzler(SkSwizzler::kIndex, colorPtr, dst
Info, opts)); |
456 colorPtr, dstInfo, zeroInit)); | |
457 if (nullptr != fSwizzler.get()) { | 451 if (nullptr != fSwizzler.get()) { |
458 return kSuccess; | 452 return kSuccess; |
459 } | 453 } |
460 return kUnimplemented; | 454 return kUnimplemented; |
461 } | 455 } |
462 | 456 |
463 bool SkGifCodec::readRow() { | 457 bool SkGifCodec::readRow() { |
464 return GIF_ERROR != DGifGetLine(fGif, fSrcBuffer.get(), fFrameRect.width()); | 458 return GIF_ERROR != DGifGetLine(fGif, fSrcBuffer.get(), fFrameRect.width()); |
465 } | 459 } |
466 | 460 |
(...skipping 11 matching lines...) Expand all Loading... |
478 return result; | 472 return result; |
479 } | 473 } |
480 | 474 |
481 if (dstInfo.dimensions() != this->getInfo().dimensions()) { | 475 if (dstInfo.dimensions() != this->getInfo().dimensions()) { |
482 return gif_error("Scaling not supported.\n", kInvalidScale); | 476 return gif_error("Scaling not supported.\n", kInvalidScale); |
483 } | 477 } |
484 | 478 |
485 // Initialize the swizzler | 479 // Initialize the swizzler |
486 if (fFrameIsSubset) { | 480 if (fFrameIsSubset) { |
487 const SkImageInfo subsetDstInfo = dstInfo.makeWH(fFrameRect.width(), fFr
ameRect.height()); | 481 const SkImageInfo subsetDstInfo = dstInfo.makeWH(fFrameRect.width(), fFr
ameRect.height()); |
488 if (kSuccess != this->initializeSwizzler(subsetDstInfo, opts.fZeroInitia
lized)) { | 482 if (kSuccess != this->initializeSwizzler(subsetDstInfo, opts)) { |
489 return gif_error("Could not initialize swizzler.\n", kUnimplemented)
; | 483 return gif_error("Could not initialize swizzler.\n", kUnimplemented)
; |
490 } | 484 } |
491 | 485 |
492 // Fill the background | 486 // Fill the background |
493 SkSampler::Fill(dstInfo, dst, dstRowBytes, | 487 SkSampler::Fill(dstInfo, dst, dstRowBytes, |
494 this->getFillValue(dstInfo.colorType(), dstInfo.alphaType()), | 488 this->getFillValue(dstInfo.colorType(), dstInfo.alphaType()), |
495 opts.fZeroInitialized); | 489 opts.fZeroInitialized); |
496 | 490 |
497 // Modify the dst pointer | 491 // Modify the dst pointer |
498 const int32_t dstBytesPerPixel = SkColorTypeBytesPerPixel(dstInfo.colorT
ype()); | 492 const int32_t dstBytesPerPixel = SkColorTypeBytesPerPixel(dstInfo.colorT
ype()); |
499 dst = SkTAddOffset<void*>(dst, dstRowBytes * fFrameRect.top() + | 493 dst = SkTAddOffset<void*>(dst, dstRowBytes * fFrameRect.top() + |
500 dstBytesPerPixel * fFrameRect.left()); | 494 dstBytesPerPixel * fFrameRect.left()); |
501 } else { | 495 } else { |
502 if (kSuccess != this->initializeSwizzler(dstInfo, opts.fZeroInitialized)
) { | 496 if (kSuccess != this->initializeSwizzler(dstInfo, opts)) { |
503 return gif_error("Could not initialize swizzler.\n", kUnimplemented)
; | 497 return gif_error("Could not initialize swizzler.\n", kUnimplemented)
; |
504 } | 498 } |
505 } | 499 } |
506 | 500 |
507 // Iterate over rows of the input | 501 // Iterate over rows of the input |
508 uint32_t height = fFrameRect.height(); | 502 uint32_t height = fFrameRect.height(); |
509 for (uint32_t y = 0; y < height; y++) { | 503 for (uint32_t y = 0; y < height; y++) { |
510 if (!this->readRow()) { | 504 if (!this->readRow()) { |
511 *rowsDecoded = y; | 505 *rowsDecoded = y; |
512 return gif_error("Could not decode line.\n", kIncompleteInput); | 506 return gif_error("Could not decode line.\n", kIncompleteInput); |
(...skipping 15 matching lines...) Expand all Loading... |
528 const SkCodec::Options& opts, SkPMColor inputColorPtr[], int* inputColor
Count) { | 522 const SkCodec::Options& opts, SkPMColor inputColorPtr[], int* inputColor
Count) { |
529 | 523 |
530 Result result = this->prepareToDecode(dstInfo, inputColorPtr, inputColorCoun
t, this->options()); | 524 Result result = this->prepareToDecode(dstInfo, inputColorPtr, inputColorCoun
t, this->options()); |
531 if (kSuccess != result) { | 525 if (kSuccess != result) { |
532 return result; | 526 return result; |
533 } | 527 } |
534 | 528 |
535 // Initialize the swizzler | 529 // Initialize the swizzler |
536 if (fFrameIsSubset) { | 530 if (fFrameIsSubset) { |
537 const SkImageInfo subsetDstInfo = dstInfo.makeWH(fFrameRect.width(), fFr
ameRect.height()); | 531 const SkImageInfo subsetDstInfo = dstInfo.makeWH(fFrameRect.width(), fFr
ameRect.height()); |
538 if (kSuccess != this->initializeSwizzler(subsetDstInfo, opts.fZeroInitia
lized)) { | 532 if (kSuccess != this->initializeSwizzler(subsetDstInfo, opts)) { |
539 return gif_error("Could not initialize swizzler.\n", kUnimplemented)
; | 533 return gif_error("Could not initialize swizzler.\n", kUnimplemented)
; |
540 } | 534 } |
541 } else { | 535 } else { |
542 if (kSuccess != this->initializeSwizzler(dstInfo, opts.fZeroInitialized)
) { | 536 if (kSuccess != this->initializeSwizzler(dstInfo, opts)) { |
543 return gif_error("Could not initialize swizzler.\n", kUnimplemented)
; | 537 return gif_error("Could not initialize swizzler.\n", kUnimplemented)
; |
544 } | 538 } |
545 } | 539 } |
546 | 540 |
547 return kSuccess; | 541 return kSuccess; |
548 } | 542 } |
549 | 543 |
550 int SkGifCodec::onGetScanlines(void* dst, int count, size_t rowBytes) { | 544 int SkGifCodec::onGetScanlines(void* dst, int count, size_t rowBytes) { |
551 int rowsBeforeFrame = 0; | 545 int rowsBeforeFrame = 0; |
552 int rowsAfterFrame = 0; | 546 int rowsAfterFrame = 0; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
593 | 587 |
594 int SkGifCodec::onOutputScanline(int inputScanline) const { | 588 int SkGifCodec::onOutputScanline(int inputScanline) const { |
595 if (fGif->Image.Interlace) { | 589 if (fGif->Image.Interlace) { |
596 if (inputScanline < fFrameRect.top() || inputScanline >= fFrameRect.bott
om()) { | 590 if (inputScanline < fFrameRect.top() || inputScanline >= fFrameRect.bott
om()) { |
597 return inputScanline; | 591 return inputScanline; |
598 } | 592 } |
599 return get_output_row_interlaced(inputScanline - fFrameRect.top(), fFram
eRect.height()); | 593 return get_output_row_interlaced(inputScanline - fFrameRect.top(), fFram
eRect.height()); |
600 } | 594 } |
601 return inputScanline; | 595 return inputScanline; |
602 } | 596 } |
OLD | NEW |