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

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: Response to comments 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
« no previous file with comments | « src/codec/SkAndroidCodec.cpp ('k') | src/codec/SkSampledCodec.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 const SkIRect* frameRect = fFrameIsSubset ? &fFrameRect : nullptr;
446 fSwizzler.reset(SkSwizzler::CreateSwizzler(SkSwizzler::kIndex, colorPtr, dst Info, opts,
447 frameRect));
448
445 if (nullptr != fSwizzler.get()) { 449 if (nullptr != fSwizzler.get()) {
446 return kSuccess; 450 return kSuccess;
447 } 451 }
448 return kUnimplemented; 452 return kUnimplemented;
449 } 453 }
450 454
451 bool SkGifCodec::readRow() { 455 bool SkGifCodec::readRow() {
452 return GIF_ERROR != DGifGetLine(fGif, fSrcBuffer.get(), fFrameRect.width()); 456 return GIF_ERROR != DGifGetLine(fGif, fSrcBuffer.get(), fFrameRect.width());
453 } 457 }
454 458
(...skipping 10 matching lines...) Expand all
465 if (kSuccess != result) { 469 if (kSuccess != result) {
466 return result; 470 return result;
467 } 471 }
468 472
469 if (dstInfo.dimensions() != this->getInfo().dimensions()) { 473 if (dstInfo.dimensions() != this->getInfo().dimensions()) {
470 return gif_error("Scaling not supported.\n", kInvalidScale); 474 return gif_error("Scaling not supported.\n", kInvalidScale);
471 } 475 }
472 476
473 // Initialize the swizzler 477 // Initialize the swizzler
474 if (fFrameIsSubset) { 478 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 479 // Fill the background
481 SkSampler::Fill(dstInfo, dst, dstRowBytes, 480 SkSampler::Fill(dstInfo, dst, dstRowBytes,
482 this->getFillValue(dstInfo.colorType(), dstInfo.alphaType()), 481 this->getFillValue(dstInfo.colorType(), dstInfo.alphaType()),
483 opts.fZeroInitialized); 482 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 } 483 }
494 484
495 // Iterate over rows of the input 485 // Iterate over rows of the input
496 uint32_t height = fFrameRect.height(); 486 for (int y = fFrameRect.top(); y < fFrameRect.bottom(); y++) {
497 for (uint32_t y = 0; y < height; y++) {
498 if (!this->readRow()) { 487 if (!this->readRow()) {
499 *rowsDecoded = y; 488 *rowsDecoded = y;
500 return gif_error("Could not decode line.\n", kIncompleteInput); 489 return gif_error("Could not decode line.\n", kIncompleteInput);
501 } 490 }
502 void* dstRow = SkTAddOffset<void>(dst, dstRowBytes * this->outputScanlin e(y)); 491 void* dstRow = SkTAddOffset<void>(dst, dstRowBytes * this->outputScanlin e(y));
503 fSwizzler->swizzle(dstRow, fSrcBuffer.get()); 492 fSwizzler->swizzle(dstRow, fSrcBuffer.get());
504 } 493 }
505 return kSuccess; 494 return kSuccess;
506 } 495 }
507 496
508 // FIXME: This is similar to the implementation for bmp and png. Can we share m ore code or 497 // FIXME: This is similar to the implementation for bmp and png. Can we share m ore code or
509 // possibly make this non-virtual? 498 // possibly make this non-virtual?
510 uint32_t SkGifCodec::onGetFillValue(SkColorType colorType, SkAlphaType alphaType ) const { 499 uint32_t SkGifCodec::onGetFillValue(SkColorType colorType, SkAlphaType alphaType ) const {
511 const SkPMColor* colorPtr = get_color_ptr(fColorTable.get()); 500 const SkPMColor* colorPtr = get_color_ptr(fColorTable.get());
512 return get_color_table_fill_value(colorType, colorPtr, fFillIndex); 501 return get_color_table_fill_value(colorType, colorPtr, fFillIndex);
513 } 502 }
514 503
515 SkCodec::Result SkGifCodec::onStartScanlineDecode(const SkImageInfo& dstInfo, 504 SkCodec::Result SkGifCodec::onStartScanlineDecode(const SkImageInfo& dstInfo,
516 const SkCodec::Options& opts, SkPMColor inputColorPtr[], int* inputColor Count) { 505 const SkCodec::Options& opts, SkPMColor inputColorPtr[], int* inputColor Count) {
517 506 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 } 507 }
537 508
538 int SkGifCodec::onGetScanlines(void* dst, int count, size_t rowBytes) { 509 int SkGifCodec::onGetScanlines(void* dst, int count, size_t rowBytes) {
539 int rowsBeforeFrame = 0; 510 int rowsBeforeFrame = 0;
540 int rowsAfterFrame = 0; 511 int rowsAfterFrame = 0;
541 int rowsInFrame = count; 512 int rowsInFrame = count;
542 if (fFrameIsSubset) { 513 if (fFrameIsSubset) {
543 // Fill the requested rows 514 // Fill the requested rows
544 SkImageInfo fillInfo = this->dstInfo().makeWH(this->dstInfo().width(), c ount); 515 SkImageInfo fillInfo = this->dstInfo().makeWH(this->dstInfo().width(), c ount);
545 uint32_t fillValue = this->onGetFillValue(this->dstInfo().colorType(), 516 uint32_t fillValue = this->onGetFillValue(this->dstInfo().colorType(),
546 this->dstInfo().alphaType()); 517 this->dstInfo().alphaType());
547 SkSampler::Fill(fillInfo, dst, rowBytes, fillValue, this->options().fZer oInitialized); 518 fSwizzler->fill(fillInfo, dst, rowBytes, fillValue, this->options().fZer oInitialized);
548 519
549 // Do nothing for rows before the image frame 520 // Do nothing for rows before the image frame
550 rowsBeforeFrame = SkTMax(0, fFrameRect.top() - this->INHERITED::nextScan line()); 521 rowsBeforeFrame = SkTMax(0, fFrameRect.top() - this->INHERITED::nextScan line());
551 rowsInFrame = SkTMax(0, rowsInFrame - rowsBeforeFrame); 522 rowsInFrame = SkTMax(0, rowsInFrame - rowsBeforeFrame);
552 dst = SkTAddOffset<void>(dst, rowBytes * rowsBeforeFrame); 523 dst = SkTAddOffset<void>(dst, rowBytes * rowsBeforeFrame);
553 524
554 // Do nothing for rows after the image frame 525 // Do nothing for rows after the image frame
555 rowsAfterFrame = SkTMax(0, 526 rowsAfterFrame = SkTMax(0,
556 this->INHERITED::nextScanline() + rowsInFrame - fFrameRect.botto m()); 527 this->INHERITED::nextScanline() + rowsInFrame - fFrameRect.botto m());
557 rowsInFrame = SkTMax(0, rowsInFrame - rowsAfterFrame); 528 rowsInFrame = SkTMax(0, rowsInFrame - rowsAfterFrame);
558
559 // Adjust dst pointer for left offset
560 int offset = SkColorTypeBytesPerPixel(this->dstInfo().colorType()) * fFr ameRect.left();
561 dst = SkTAddOffset<void>(dst, offset);
562 } 529 }
563 530
564 for (int i = 0; i < rowsInFrame; i++) { 531 for (int i = 0; i < rowsInFrame; i++) {
565 if (!this->readRow()) { 532 if (!this->readRow()) {
566 return i + rowsBeforeFrame; 533 return i + rowsBeforeFrame;
567 } 534 }
568 fSwizzler->swizzle(dst, fSrcBuffer.get()); 535 fSwizzler->swizzle(dst, fSrcBuffer.get());
569 dst = SkTAddOffset<void>(dst, rowBytes); 536 dst = SkTAddOffset<void>(dst, rowBytes);
570 } 537 }
571 538
572 return count; 539 return count;
573 } 540 }
574 541
575 SkCodec::SkScanlineOrder SkGifCodec::onGetScanlineOrder() const { 542 SkCodec::SkScanlineOrder SkGifCodec::onGetScanlineOrder() const {
576 if (fGif->Image.Interlace) { 543 if (fGif->Image.Interlace) {
577 return kOutOfOrder_SkScanlineOrder; 544 return kOutOfOrder_SkScanlineOrder;
578 } 545 }
579 return kTopDown_SkScanlineOrder; 546 return kTopDown_SkScanlineOrder;
580 } 547 }
581 548
582 int SkGifCodec::onOutputScanline(int inputScanline) const { 549 int SkGifCodec::onOutputScanline(int inputScanline) const {
583 if (fGif->Image.Interlace) { 550 if (fGif->Image.Interlace) {
584 if (inputScanline < fFrameRect.top() || inputScanline >= fFrameRect.bott om()) { 551 if (inputScanline < fFrameRect.top() || inputScanline >= fFrameRect.bott om()) {
585 return inputScanline; 552 return inputScanline;
586 } 553 }
587 return get_output_row_interlaced(inputScanline - fFrameRect.top(), fFram eRect.height()); 554 return get_output_row_interlaced(inputScanline - fFrameRect.top(), fFram eRect.height()) +
555 fFrameRect.top();
588 } 556 }
589 return inputScanline; 557 return inputScanline;
590 } 558 }
OLDNEW
« no previous file with comments | « src/codec/SkAndroidCodec.cpp ('k') | src/codec/SkSampledCodec.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698