Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(35)

Side by Side Diff: src/codec/SkCodec_libgif.cpp

Issue 1445313002: Make SkAndroidCodec support gif (Closed) Base URL: https://skia.googlesource.com/skia.git@bmp
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 418 matching lines...) Expand 10 before | Expand all | Expand 10 after
429 SkCodec::Result SkGifCodec::prepareToDecode(const SkImageInfo& dstInfo, SkPMColo r* inputColorPtr, 429 SkCodec::Result SkGifCodec::prepareToDecode(const SkImageInfo& dstInfo, SkPMColo r* inputColorPtr,
430 int* inputColorCount, const Options& opts) { 430 int* inputColorCount, const Options& opts) {
431 // Check for valid input parameters 431 // Check for valid input parameters
432 if (!conversion_possible(dstInfo, this->getInfo())) { 432 if (!conversion_possible(dstInfo, this->getInfo())) {
433 return gif_error("Cannot convert input type to output type.\n", 433 return gif_error("Cannot convert input type to output type.\n",
434 kInvalidConversion); 434 kInvalidConversion);
435 } 435 }
436 436
437 // Initialize color table and copy to the client if necessary 437 // Initialize color table and copy to the client if necessary
438 this->initializeColorTable(dstInfo, inputColorPtr, inputColorCount); 438 this->initializeColorTable(dstInfo, inputColorPtr, inputColorCount);
439 return kSuccess; 439
440 return this->initializeSwizzler(dstInfo, opts);
440 } 441 }
441 442
442 SkCodec::Result SkGifCodec::initializeSwizzler(const SkImageInfo& dstInfo, const Options& opts) { 443 SkCodec::Result SkGifCodec::initializeSwizzler(const SkImageInfo& dstInfo, const Options& opts) {
443 const SkPMColor* colorPtr = get_color_ptr(fColorTable.get()); 444 const SkPMColor* colorPtr = get_color_ptr(fColorTable.get());
444 fSwizzler.reset(SkSwizzler::CreateSwizzler(SkSwizzler::kIndex, colorPtr, dst Info, opts)); 445 if (fFrameIsSubset) {
msarett 2015/11/16 23:20:58 This is a just a refactor to share some more code.
scroggo 2015/11/17 14:56:26 +1 What do you think about creating a pointer loc
msarett 2015/11/17 18:00:50 sgtm
446 fSwizzler.reset(SkSwizzler::CreateSwizzler(SkSwizzler::kIndex, colorPtr, dstInfo, opts,
447 &fFrameRect));
448 } else {
449 fSwizzler.reset(SkSwizzler::CreateSwizzler(SkSwizzler::kIndex, colorPtr, dstInfo, opts));
450 }
445 if (nullptr != fSwizzler.get()) { 451 if (nullptr != fSwizzler.get()) {
446 return kSuccess; 452 return kSuccess;
447 } 453 }
448 return kUnimplemented; 454 return kUnimplemented;
449 } 455 }
450 456
451 bool SkGifCodec::readRow() { 457 bool SkGifCodec::readRow() {
452 return GIF_ERROR != DGifGetLine(fGif, fSrcBuffer.get(), fFrameRect.width()); 458 return GIF_ERROR != DGifGetLine(fGif, fSrcBuffer.get(), fFrameRect.width());
453 } 459 }
454 460
(...skipping 10 matching lines...) Expand all
465 if (kSuccess != result) { 471 if (kSuccess != result) {
466 return result; 472 return result;
467 } 473 }
468 474
469 if (dstInfo.dimensions() != this->getInfo().dimensions()) { 475 if (dstInfo.dimensions() != this->getInfo().dimensions()) {
470 return gif_error("Scaling not supported.\n", kInvalidScale); 476 return gif_error("Scaling not supported.\n", kInvalidScale);
471 } 477 }
472 478
473 // Initialize the swizzler 479 // Initialize the swizzler
474 if (fFrameIsSubset) { 480 if (fFrameIsSubset) {
475 const SkImageInfo subsetDstInfo = dstInfo.makeWH(fFrameRect.width(), fFr ameRect.height());
476 if (kSuccess != this->initializeSwizzler(subsetDstInfo, opts)) {
477 return gif_error("Could not initialize swizzler.\n", kUnimplemented) ;
478 }
479
480 // Fill the background 481 // Fill the background
481 SkSampler::Fill(dstInfo, dst, dstRowBytes, 482 SkSampler::Fill(dstInfo, dst, dstRowBytes,
482 this->getFillValue(dstInfo.colorType(), dstInfo.alphaType()), 483 this->getFillValue(dstInfo.colorType(), dstInfo.alphaType()),
483 opts.fZeroInitialized); 484 opts.fZeroInitialized);
484
485 // Modify the dst pointer
486 const int32_t dstBytesPerPixel = SkColorTypeBytesPerPixel(dstInfo.colorT ype());
487 dst = SkTAddOffset<void*>(dst, dstRowBytes * fFrameRect.top() +
488 dstBytesPerPixel * fFrameRect.left());
489 } else {
490 if (kSuccess != this->initializeSwizzler(dstInfo, opts)) {
491 return gif_error("Could not initialize swizzler.\n", kUnimplemented) ;
492 }
493 } 485 }
494 486
495 // Iterate over rows of the input 487 // Iterate over rows of the input
496 uint32_t height = fFrameRect.height(); 488 for (int y = fFrameRect.top(); y < fFrameRect.bottom(); y++) {
msarett 2015/11/16 23:20:58 Bug fix, so outputScanline(y) gives us the right a
497 for (uint32_t y = 0; y < height; y++) {
498 if (!this->readRow()) { 489 if (!this->readRow()) {
499 *rowsDecoded = y; 490 *rowsDecoded = y;
500 return gif_error("Could not decode line.\n", kIncompleteInput); 491 return gif_error("Could not decode line.\n", kIncompleteInput);
501 } 492 }
502 void* dstRow = SkTAddOffset<void>(dst, dstRowBytes * this->outputScanlin e(y)); 493 void* dstRow = SkTAddOffset<void>(dst, dstRowBytes * this->outputScanlin e(y));
503 fSwizzler->swizzle(dstRow, fSrcBuffer.get()); 494 fSwizzler->swizzle(dstRow, fSrcBuffer.get());
504 } 495 }
505 return kSuccess; 496 return kSuccess;
506 } 497 }
507 498
508 // FIXME: This is similar to the implementation for bmp and png. Can we share m ore code or 499 // FIXME: This is similar to the implementation for bmp and png. Can we share m ore code or
509 // possibly make this non-virtual? 500 // possibly make this non-virtual?
510 uint32_t SkGifCodec::onGetFillValue(SkColorType colorType, SkAlphaType alphaType ) const { 501 uint32_t SkGifCodec::onGetFillValue(SkColorType colorType, SkAlphaType alphaType ) const {
511 const SkPMColor* colorPtr = get_color_ptr(fColorTable.get()); 502 const SkPMColor* colorPtr = get_color_ptr(fColorTable.get());
512 return get_color_table_fill_value(colorType, colorPtr, fFillIndex); 503 return get_color_table_fill_value(colorType, colorPtr, fFillIndex);
513 } 504 }
514 505
515 SkCodec::Result SkGifCodec::onStartScanlineDecode(const SkImageInfo& dstInfo, 506 SkCodec::Result SkGifCodec::onStartScanlineDecode(const SkImageInfo& dstInfo,
516 const SkCodec::Options& opts, SkPMColor inputColorPtr[], int* inputColor Count) { 507 const SkCodec::Options& opts, SkPMColor inputColorPtr[], int* inputColor Count) {
517 508 return this->prepareToDecode(dstInfo, inputColorPtr, inputColorCount, this-> options());
518 Result result = this->prepareToDecode(dstInfo, inputColorPtr, inputColorCoun t, this->options());
519 if (kSuccess != result) {
520 return result;
521 }
522
523 // Initialize the swizzler
524 if (fFrameIsSubset) {
525 const SkImageInfo subsetDstInfo = dstInfo.makeWH(fFrameRect.width(), fFr ameRect.height());
526 if (kSuccess != this->initializeSwizzler(subsetDstInfo, opts)) {
527 return gif_error("Could not initialize swizzler.\n", kUnimplemented) ;
528 }
529 } else {
530 if (kSuccess != this->initializeSwizzler(dstInfo, opts)) {
531 return gif_error("Could not initialize swizzler.\n", kUnimplemented) ;
532 }
533 }
534
535 return kSuccess;
536 } 509 }
537 510
538 int SkGifCodec::onGetScanlines(void* dst, int count, size_t rowBytes) { 511 int SkGifCodec::onGetScanlines(void* dst, int count, size_t rowBytes) {
539 int rowsBeforeFrame = 0; 512 int rowsBeforeFrame = 0;
540 int rowsAfterFrame = 0; 513 int rowsAfterFrame = 0;
541 int rowsInFrame = count; 514 int rowsInFrame = count;
542 if (fFrameIsSubset) { 515 if (fFrameIsSubset) {
543 // Fill the requested rows 516 // Fill the requested rows
544 SkImageInfo fillInfo = this->dstInfo().makeWH(this->dstInfo().width(), c ount); 517 SkImageInfo fillInfo = this->dstInfo().makeWH(this->dstInfo().width(), c ount);
545 uint32_t fillValue = this->onGetFillValue(this->dstInfo().colorType(), 518 uint32_t fillValue = this->onGetFillValue(this->dstInfo().colorType(),
546 this->dstInfo().alphaType()); 519 this->dstInfo().alphaType());
547 SkSampler::Fill(fillInfo, dst, rowBytes, fillValue, this->options().fZer oInitialized); 520 fSwizzler->fill(fillInfo, dst, rowBytes, fillValue, this->options().fZer oInitialized);
548 521
549 // Do nothing for rows before the image frame 522 // Do nothing for rows before the image frame
550 rowsBeforeFrame = SkTMax(0, fFrameRect.top() - this->INHERITED::nextScan line()); 523 rowsBeforeFrame = SkTMax(0, fFrameRect.top() - this->INHERITED::nextScan line());
551 rowsInFrame = SkTMax(0, rowsInFrame - rowsBeforeFrame); 524 rowsInFrame = SkTMax(0, rowsInFrame - rowsBeforeFrame);
552 dst = SkTAddOffset<void>(dst, rowBytes * rowsBeforeFrame); 525 dst = SkTAddOffset<void>(dst, rowBytes * rowsBeforeFrame);
553 526
554 // Do nothing for rows after the image frame 527 // Do nothing for rows after the image frame
555 rowsAfterFrame = SkTMax(0, 528 rowsAfterFrame = SkTMax(0,
556 this->INHERITED::nextScanline() + rowsInFrame - fFrameRect.botto m()); 529 this->INHERITED::nextScanline() + rowsInFrame - fFrameRect.botto m());
557 rowsInFrame = SkTMax(0, rowsInFrame - rowsAfterFrame); 530 rowsInFrame = SkTMax(0, rowsInFrame - rowsAfterFrame);
558
msarett 2015/11/16 23:20:58 We handle this inside the swizzler now. If we try
559 // Adjust dst pointer for left offset
560 int offset = SkColorTypeBytesPerPixel(this->dstInfo().colorType()) * fFr ameRect.left();
561 dst = SkTAddOffset<void>(dst, offset);
562 } 531 }
563 532
564 for (int i = 0; i < rowsInFrame; i++) { 533 for (int i = 0; i < rowsInFrame; i++) {
565 if (!this->readRow()) { 534 if (!this->readRow()) {
566 return i + rowsBeforeFrame; 535 return i + rowsBeforeFrame;
567 } 536 }
568 fSwizzler->swizzle(dst, fSrcBuffer.get()); 537 fSwizzler->swizzle(dst, fSrcBuffer.get());
569 dst = SkTAddOffset<void>(dst, rowBytes); 538 dst = SkTAddOffset<void>(dst, rowBytes);
570 } 539 }
571 540
572 return count; 541 return count;
573 } 542 }
574 543
575 SkCodec::SkScanlineOrder SkGifCodec::onGetScanlineOrder() const { 544 SkCodec::SkScanlineOrder SkGifCodec::onGetScanlineOrder() const {
576 if (fGif->Image.Interlace) { 545 if (fGif->Image.Interlace) {
577 return kOutOfOrder_SkScanlineOrder; 546 return kOutOfOrder_SkScanlineOrder;
578 } 547 }
579 return kTopDown_SkScanlineOrder; 548 return kTopDown_SkScanlineOrder;
580 } 549 }
581 550
582 int SkGifCodec::onOutputScanline(int inputScanline) const { 551 int SkGifCodec::onOutputScanline(int inputScanline) const {
583 if (fGif->Image.Interlace) { 552 if (fGif->Image.Interlace) {
584 if (inputScanline < fFrameRect.top() || inputScanline >= fFrameRect.bott om()) { 553 if (inputScanline < fFrameRect.top() || inputScanline >= fFrameRect.bott om()) {
585 return inputScanline; 554 return inputScanline;
586 } 555 }
587 return get_output_row_interlaced(inputScanline - fFrameRect.top(), fFram eRect.height()); 556 return get_output_row_interlaced(inputScanline - fFrameRect.top(), fFram eRect.height()) +
557 fFrameRect.top();
msarett 2015/11/16 23:20:58 Bug fix.
588 } 558 }
589 return inputScanline; 559 return inputScanline;
590 } 560 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698