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

Side by Side Diff: src/images/SkImageDecoder_libwebp.cpp

Issue 176963003: Upstream changes from Android (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 6 years, 9 months 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 | Annotate | Revision Log
« no previous file with comments | « src/core/SkPaint.cpp ('k') | no next file » | 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 2010, The Android Open Source Project 2 * Copyright 2010, The Android Open Source Project
3 * 3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License. 5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at 6 * You may obtain a copy of the License at
7 * 7 *
8 * http://www.apache.org/licenses/LICENSE-2.0 8 * http://www.apache.org/licenses/LICENSE-2.0
9 * 9 *
10 * Unless required by applicable law or agreed to in writing, software 10 * Unless required by applicable law or agreed to in writing, software
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after
437 this->shouldPremultiply())) { 437 this->shouldPremultiply())) {
438 return false; 438 return false;
439 } 439 }
440 440
441 // Decode the WebP image data stream using WebP incremental decoding. 441 // Decode the WebP image data stream using WebP incremental decoding.
442 return webp_idecode(stream, &config); 442 return webp_idecode(stream, &config);
443 } 443 }
444 444
445 /////////////////////////////////////////////////////////////////////////////// 445 ///////////////////////////////////////////////////////////////////////////////
446 446
447 #include "SkUnPreMultiply.h"
448
447 typedef void (*ScanlineImporter)(const uint8_t* in, uint8_t* out, int width, 449 typedef void (*ScanlineImporter)(const uint8_t* in, uint8_t* out, int width,
448 const SkPMColor* SK_RESTRICT ctable); 450 const SkPMColor* SK_RESTRICT ctable);
449 451
450 static void ARGB_8888_To_RGB(const uint8_t* in, uint8_t* rgb, int width, 452 static void ARGB_8888_To_RGB(const uint8_t* in, uint8_t* rgb, int width,
451 const SkPMColor*) { 453 const SkPMColor*) {
452 const uint32_t* SK_RESTRICT src = (const uint32_t*)in; 454 const uint32_t* SK_RESTRICT src = (const uint32_t*)in;
453 for (int i = 0; i < width; ++i) { 455 for (int i = 0; i < width; ++i) {
454 const uint32_t c = *src++; 456 const uint32_t c = *src++;
455 rgb[0] = SkGetPackedR32(c); 457 rgb[0] = SkGetPackedR32(c);
456 rgb[1] = SkGetPackedG32(c); 458 rgb[1] = SkGetPackedG32(c);
457 rgb[2] = SkGetPackedB32(c); 459 rgb[2] = SkGetPackedB32(c);
458 rgb += 3; 460 rgb += 3;
459 } 461 }
460 } 462 }
461 463
464 static void ARGB_8888_To_RGBA(const uint8_t* in, uint8_t* rgb, int width,
465 const SkPMColor*) {
466 const uint32_t* SK_RESTRICT src = (const uint32_t*)in;
467 const SkUnPreMultiply::Scale* SK_RESTRICT table =
468 SkUnPreMultiply::GetScaleTable();
469 for (int i = 0; i < width; ++i) {
470 const uint32_t c = *src++;
471 uint8_t a = SkGetPackedA32(c);
472 uint8_t r = SkGetPackedR32(c);
473 uint8_t g = SkGetPackedG32(c);
474 uint8_t b = SkGetPackedB32(c);
475 if (0 != a && 255 != a) {
476 SkUnPreMultiply::Scale scale = table[a];
477 r = SkUnPreMultiply::ApplyScale(scale, r);
478 g = SkUnPreMultiply::ApplyScale(scale, g);
479 b = SkUnPreMultiply::ApplyScale(scale, b);
480 }
481 rgb[0] = r;
482 rgb[1] = g;
483 rgb[2] = b;
484 rgb[3] = a;
485 rgb += 4;
486 }
487 }
488
462 static void RGB_565_To_RGB(const uint8_t* in, uint8_t* rgb, int width, 489 static void RGB_565_To_RGB(const uint8_t* in, uint8_t* rgb, int width,
463 const SkPMColor*) { 490 const SkPMColor*) {
464 const uint16_t* SK_RESTRICT src = (const uint16_t*)in; 491 const uint16_t* SK_RESTRICT src = (const uint16_t*)in;
465 for (int i = 0; i < width; ++i) { 492 for (int i = 0; i < width; ++i) {
466 const uint16_t c = *src++; 493 const uint16_t c = *src++;
467 rgb[0] = SkPacked16ToR32(c); 494 rgb[0] = SkPacked16ToR32(c);
468 rgb[1] = SkPacked16ToG32(c); 495 rgb[1] = SkPacked16ToG32(c);
469 rgb[2] = SkPacked16ToB32(c); 496 rgb[2] = SkPacked16ToB32(c);
470 rgb += 3; 497 rgb += 3;
471 } 498 }
472 } 499 }
473 500
474 static void ARGB_4444_To_RGB(const uint8_t* in, uint8_t* rgb, int width, 501 static void ARGB_4444_To_RGB(const uint8_t* in, uint8_t* rgb, int width,
475 const SkPMColor*) { 502 const SkPMColor*) {
476 const SkPMColor16* SK_RESTRICT src = (const SkPMColor16*)in; 503 const SkPMColor16* SK_RESTRICT src = (const SkPMColor16*)in;
477 for (int i = 0; i < width; ++i) { 504 for (int i = 0; i < width; ++i) {
478 const SkPMColor16 c = *src++; 505 const SkPMColor16 c = *src++;
479 rgb[0] = SkPacked4444ToR32(c); 506 rgb[0] = SkPacked4444ToR32(c);
480 rgb[1] = SkPacked4444ToG32(c); 507 rgb[1] = SkPacked4444ToG32(c);
481 rgb[2] = SkPacked4444ToB32(c); 508 rgb[2] = SkPacked4444ToB32(c);
482 rgb += 3; 509 rgb += 3;
483 } 510 }
484 } 511 }
485 512
513 static void ARGB_4444_To_RGBA(const uint8_t* in, uint8_t* rgb, int width,
514 const SkPMColor*) {
515 const SkPMColor16* SK_RESTRICT src = (const SkPMColor16*)in;
516 const SkUnPreMultiply::Scale* SK_RESTRICT table =
517 SkUnPreMultiply::GetScaleTable();
518 for (int i = 0; i < width; ++i) {
519 const SkPMColor16 c = *src++;
520 uint8_t a = SkPacked4444ToA32(c);
521 uint8_t r = SkPacked4444ToR32(c);
522 uint8_t g = SkPacked4444ToG32(c);
523 uint8_t b = SkPacked4444ToB32(c);
524 if (0 != a && 255 != a) {
525 SkUnPreMultiply::Scale scale = table[a];
526 r = SkUnPreMultiply::ApplyScale(scale, r);
527 g = SkUnPreMultiply::ApplyScale(scale, g);
528 b = SkUnPreMultiply::ApplyScale(scale, b);
529 }
530 rgb[0] = r;
531 rgb[1] = g;
532 rgb[2] = b;
533 rgb[3] = a;
534 rgb += 4;
535 }
536 }
537
486 static void Index8_To_RGB(const uint8_t* in, uint8_t* rgb, int width, 538 static void Index8_To_RGB(const uint8_t* in, uint8_t* rgb, int width,
487 const SkPMColor* SK_RESTRICT ctable) { 539 const SkPMColor* SK_RESTRICT ctable) {
488 const uint8_t* SK_RESTRICT src = (const uint8_t*)in; 540 const uint8_t* SK_RESTRICT src = (const uint8_t*)in;
489 for (int i = 0; i < width; ++i) { 541 for (int i = 0; i < width; ++i) {
490 const uint32_t c = ctable[*src++]; 542 const uint32_t c = ctable[*src++];
491 rgb[0] = SkGetPackedR32(c); 543 rgb[0] = SkGetPackedR32(c);
492 rgb[1] = SkGetPackedG32(c); 544 rgb[1] = SkGetPackedG32(c);
493 rgb[2] = SkGetPackedB32(c); 545 rgb[2] = SkGetPackedB32(c);
494 rgb += 3; 546 rgb += 3;
495 } 547 }
496 } 548 }
497 549
498 static ScanlineImporter ChooseImporter(const SkBitmap::Config& config) { 550 static ScanlineImporter ChooseImporter(const SkBitmap::Config& config,
551 bool hasAlpha,
552 int* bpp) {
499 switch (config) { 553 switch (config) {
500 case SkBitmap::kARGB_8888_Config: 554 case SkBitmap::kARGB_8888_Config:
501 return ARGB_8888_To_RGB; 555 if (hasAlpha) {
556 *bpp = 4;
557 return ARGB_8888_To_RGBA;
558 } else {
559 *bpp = 3;
560 return ARGB_8888_To_RGB;
561 }
562 case SkBitmap::kARGB_4444_Config:
563 if (hasAlpha) {
564 *bpp = 4;
565 return ARGB_4444_To_RGBA;
566 } else {
567 *bpp = 3;
568 return ARGB_4444_To_RGB;
569 }
502 case SkBitmap::kRGB_565_Config: 570 case SkBitmap::kRGB_565_Config:
571 *bpp = 3;
503 return RGB_565_To_RGB; 572 return RGB_565_To_RGB;
504 case SkBitmap::kARGB_4444_Config:
505 return ARGB_4444_To_RGB;
506 case SkBitmap::kIndex8_Config: 573 case SkBitmap::kIndex8_Config:
574 *bpp = 3;
507 return Index8_To_RGB; 575 return Index8_To_RGB;
508 default: 576 default:
509 return NULL; 577 return NULL;
510 } 578 }
511 } 579 }
512 580
513 static int stream_writer(const uint8_t* data, size_t data_size, 581 static int stream_writer(const uint8_t* data, size_t data_size,
514 const WebPPicture* const picture) { 582 const WebPPicture* const picture) {
515 SkWStream* const stream = (SkWStream*)picture->custom_ptr; 583 SkWStream* const stream = (SkWStream*)picture->custom_ptr;
516 return stream->write(data, data_size) ? 1 : 0; 584 return stream->write(data, data_size) ? 1 : 0;
517 } 585 }
518 586
519 class SkWEBPImageEncoder : public SkImageEncoder { 587 class SkWEBPImageEncoder : public SkImageEncoder {
520 protected: 588 protected:
521 virtual bool onEncode(SkWStream* stream, const SkBitmap& bm, int quality) SK _OVERRIDE; 589 virtual bool onEncode(SkWStream* stream, const SkBitmap& bm, int quality) SK _OVERRIDE;
522 590
523 private: 591 private:
524 typedef SkImageEncoder INHERITED; 592 typedef SkImageEncoder INHERITED;
525 }; 593 };
526 594
527 bool SkWEBPImageEncoder::onEncode(SkWStream* stream, const SkBitmap& bm, 595 bool SkWEBPImageEncoder::onEncode(SkWStream* stream, const SkBitmap& bm,
528 int quality) { 596 int quality) {
529 const SkBitmap::Config config = bm.config(); 597 const SkBitmap::Config config = bm.config();
530 const ScanlineImporter scanline_import = ChooseImporter(config); 598 const bool hasAlpha = !bm.isOpaque();
599 int bpp = -1;
600 const ScanlineImporter scanline_import = ChooseImporter(config, hasAlpha,
601 &bpp);
531 if (NULL == scanline_import) { 602 if (NULL == scanline_import) {
532 return false; 603 return false;
533 } 604 }
605 if (-1 == bpp) {
606 return false;
607 }
534 608
535 SkAutoLockPixels alp(bm); 609 SkAutoLockPixels alp(bm);
536 SkAutoLockColors ctLocker; 610 SkAutoLockColors ctLocker;
537 if (NULL == bm.getPixels()) { 611 if (NULL == bm.getPixels()) {
538 return false; 612 return false;
539 } 613 }
540 614
541 WebPConfig webp_config; 615 WebPConfig webp_config;
542 if (!WebPConfigPreset(&webp_config, WEBP_PRESET_DEFAULT, (float) quality)) { 616 if (!WebPConfigPreset(&webp_config, WEBP_PRESET_DEFAULT, (float) quality)) {
543 return false; 617 return false;
544 } 618 }
545 619
546 WebPPicture pic; 620 WebPPicture pic;
547 WebPPictureInit(&pic); 621 WebPPictureInit(&pic);
548 pic.width = bm.width(); 622 pic.width = bm.width();
549 pic.height = bm.height(); 623 pic.height = bm.height();
550 pic.writer = stream_writer; 624 pic.writer = stream_writer;
551 pic.custom_ptr = (void*)stream; 625 pic.custom_ptr = (void*)stream;
552 626
553 const SkPMColor* colors = ctLocker.lockColors(bm); 627 const SkPMColor* colors = ctLocker.lockColors(bm);
554 const uint8_t* src = (uint8_t*)bm.getPixels(); 628 const uint8_t* src = (uint8_t*)bm.getPixels();
555 const int rgbStride = pic.width * 3; 629 const int rgbStride = pic.width * bpp;
556 630
557 // Import (for each scanline) the bit-map image (in appropriate color-space) 631 // Import (for each scanline) the bit-map image (in appropriate color-space)
558 // to RGB color space. 632 // to RGB color space.
559 uint8_t* rgb = new uint8_t[rgbStride * pic.height]; 633 uint8_t* rgb = new uint8_t[rgbStride * pic.height];
560 for (int y = 0; y < pic.height; ++y) { 634 for (int y = 0; y < pic.height; ++y) {
561 scanline_import(src + y * bm.rowBytes(), rgb + y * rgbStride, 635 scanline_import(src + y * bm.rowBytes(), rgb + y * rgbStride,
562 pic.width, colors); 636 pic.width, colors);
563 } 637 }
564 638
565 bool ok = SkToBool(WebPPictureImportRGB(&pic, rgb, rgbStride)); 639 bool ok;
640 if (bpp == 3) {
641 ok = SkToBool(WebPPictureImportRGB(&pic, rgb, rgbStride));
642 } else {
643 ok = SkToBool(WebPPictureImportRGBA(&pic, rgb, rgbStride));
644 }
566 delete[] rgb; 645 delete[] rgb;
567 646
568 ok = ok && WebPEncode(&webp_config, &pic); 647 ok = ok && WebPEncode(&webp_config, &pic);
569 WebPPictureFree(&pic); 648 WebPPictureFree(&pic);
570 649
571 return ok; 650 return ok;
572 } 651 }
573 652
574 653
575 /////////////////////////////////////////////////////////////////////////////// 654 ///////////////////////////////////////////////////////////////////////////////
(...skipping 19 matching lines...) Expand all
595 return SkImageDecoder::kUnknown_Format; 674 return SkImageDecoder::kUnknown_Format;
596 } 675 }
597 676
598 static SkImageEncoder* sk_libwebp_efactory(SkImageEncoder::Type t) { 677 static SkImageEncoder* sk_libwebp_efactory(SkImageEncoder::Type t) {
599 return (SkImageEncoder::kWEBP_Type == t) ? SkNEW(SkWEBPImageEncoder) : NUL L; 678 return (SkImageEncoder::kWEBP_Type == t) ? SkNEW(SkWEBPImageEncoder) : NUL L;
600 } 679 }
601 680
602 static SkImageDecoder_DecodeReg gDReg(sk_libwebp_dfactory); 681 static SkImageDecoder_DecodeReg gDReg(sk_libwebp_dfactory);
603 static SkImageDecoder_FormatReg gFormatReg(get_format_webp); 682 static SkImageDecoder_FormatReg gFormatReg(get_format_webp);
604 static SkImageEncoder_EncodeReg gEReg(sk_libwebp_efactory); 683 static SkImageEncoder_EncodeReg gEReg(sk_libwebp_efactory);
OLDNEW
« no previous file with comments | « src/core/SkPaint.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698