| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ui/gfx/codec/png_codec.h" | 5 #include "ui/gfx/codec/png_codec.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/strings/string_util.h" | 8 #include "base/strings/string_util.h" |
| 9 #include "third_party/libpng/png.h" | 9 #include "third_party/libpng/png.h" |
| 10 #include "third_party/skia/include/core/SkBitmap.h" | 10 #include "third_party/skia/include/core/SkBitmap.h" |
| (...skipping 660 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 671 png_output_color_type = PNG_COLOR_TYPE_RGB; | 671 png_output_color_type = PNG_COLOR_TYPE_RGB; |
| 672 converter = ConvertBGRAtoRGB; | 672 converter = ConvertBGRAtoRGB; |
| 673 } else { | 673 } else { |
| 674 output_color_components = 4; | 674 output_color_components = 4; |
| 675 png_output_color_type = PNG_COLOR_TYPE_RGB_ALPHA; | 675 png_output_color_type = PNG_COLOR_TYPE_RGB_ALPHA; |
| 676 converter = ConvertBetweenBGRAandRGBA; | 676 converter = ConvertBetweenBGRAandRGBA; |
| 677 } | 677 } |
| 678 break; | 678 break; |
| 679 | 679 |
| 680 case PNGCodec::FORMAT_SkBitmap: | 680 case PNGCodec::FORMAT_SkBitmap: |
| 681 input_color_components = 4; | 681 // Compare row_byte_width and size.width() to detect the format of |
| 682 if (discard_transparency) { | 682 // SkBitmap. kA8_Config (1bpp) and kARGB_8888_Config (4bpp) are the two |
| 683 output_color_components = 3; | 683 // supported formats. |
| 684 png_output_color_type = PNG_COLOR_TYPE_RGB; | 684 if (row_byte_width < 4 * size.width()) { |
| 685 converter = ConvertSkiatoRGB; | 685 // Not 4bpp, so must be 1bpp. |
| 686 // Ignore discard_transparency - it doesn't make sense in this context, |
| 687 // since alpha is the only thing we have and it needs to be used for |
| 688 // color intensity. |
| 689 input_color_components = 1; |
| 690 output_color_components = 1; |
| 691 png_output_color_type = PNG_COLOR_TYPE_GRAY; |
| 692 // |converter| is left as null |
| 686 } else { | 693 } else { |
| 687 output_color_components = 4; | 694 input_color_components = 4; |
| 688 png_output_color_type = PNG_COLOR_TYPE_RGB_ALPHA; | 695 if (discard_transparency) { |
| 689 converter = ConvertSkiatoRGBA; | 696 output_color_components = 3; |
| 697 png_output_color_type = PNG_COLOR_TYPE_RGB; |
| 698 converter = ConvertSkiatoRGB; |
| 699 } else { |
| 700 output_color_components = 4; |
| 701 png_output_color_type = PNG_COLOR_TYPE_RGB_ALPHA; |
| 702 converter = ConvertSkiatoRGBA; |
| 703 } |
| 690 } | 704 } |
| 691 break; | 705 break; |
| 692 | 706 |
| 693 default: | 707 default: |
| 694 NOTREACHED() << "Unknown pixel format"; | 708 NOTREACHED() << "Unknown pixel format"; |
| 695 return false; | 709 return false; |
| 696 } | 710 } |
| 697 | 711 |
| 698 // Row stride should be at least as long as the length of the data. | 712 // Row stride should be at least as long as the length of the data. |
| 699 DCHECK(input_color_components * size.width() <= row_byte_width); | 713 DCHECK(input_color_components * size.width() <= row_byte_width); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 712 | 726 |
| 713 PngEncoderState state(output); | 727 PngEncoderState state(output); |
| 714 bool success = DoLibpngWrite(png_ptr, info_ptr, &state, | 728 bool success = DoLibpngWrite(png_ptr, info_ptr, &state, |
| 715 size.width(), size.height(), row_byte_width, | 729 size.width(), size.height(), row_byte_width, |
| 716 input, compression_level, png_output_color_type, | 730 input, compression_level, png_output_color_type, |
| 717 output_color_components, converter, comments); | 731 output_color_components, converter, comments); |
| 718 | 732 |
| 719 return success; | 733 return success; |
| 720 } | 734 } |
| 721 | 735 |
| 736 bool InternalEncodeSkBitmap(const SkBitmap& input, |
| 737 bool discard_transparency, |
| 738 int compression_level, |
| 739 std::vector<unsigned char>* output) { |
| 740 if (input.empty() || input.isNull()) |
| 741 return false; |
| 742 int bpp = input.bytesPerPixel(); |
| 743 DCHECK(bpp == 1 || bpp == 4); // We support kA8_Config and kARGB_8888_Config. |
| 744 |
| 745 SkAutoLockPixels lock_input(input); |
| 746 unsigned char* inputAddr = bpp == 1 ? |
| 747 reinterpret_cast<unsigned char*>(input.getAddr8(0, 0)) : |
| 748 reinterpret_cast<unsigned char*>(input.getAddr32(0, 0)); // bpp = 4 |
| 749 return EncodeWithCompressionLevel( |
| 750 inputAddr, |
| 751 PNGCodec::FORMAT_SkBitmap, |
| 752 Size(input.width(), input.height()), |
| 753 static_cast<int>(input.rowBytes()), |
| 754 discard_transparency, |
| 755 std::vector<PNGCodec::Comment>(), |
| 756 compression_level, |
| 757 output); |
| 758 } |
| 759 |
| 722 | 760 |
| 723 } // namespace | 761 } // namespace |
| 724 | 762 |
| 725 // static | 763 // static |
| 726 bool PNGCodec::Encode(const unsigned char* input, ColorFormat format, | 764 bool PNGCodec::Encode(const unsigned char* input, |
| 727 const Size& size, int row_byte_width, | 765 ColorFormat format, |
| 766 const Size& size, |
| 767 int row_byte_width, |
| 728 bool discard_transparency, | 768 bool discard_transparency, |
| 729 const std::vector<Comment>& comments, | 769 const std::vector<Comment>& comments, |
| 730 std::vector<unsigned char>* output) { | 770 std::vector<unsigned char>* output) { |
| 731 return EncodeWithCompressionLevel(input, | 771 return EncodeWithCompressionLevel(input, |
| 732 format, | 772 format, |
| 733 size, | 773 size, |
| 734 row_byte_width, | 774 row_byte_width, |
| 735 discard_transparency, | 775 discard_transparency, |
| 736 comments, | 776 comments, |
| 737 Z_DEFAULT_COMPRESSION, | 777 Z_DEFAULT_COMPRESSION, |
| 738 output); | 778 output); |
| 739 } | 779 } |
| 740 | 780 |
| 741 // static | 781 // static |
| 742 bool PNGCodec::EncodeBGRASkBitmap(const SkBitmap& input, | 782 bool PNGCodec::EncodeBGRASkBitmap(const SkBitmap& input, |
| 743 bool discard_transparency, | 783 bool discard_transparency, |
| 744 std::vector<unsigned char>* output) { | 784 std::vector<unsigned char>* output) { |
| 745 static const int bbp = 4; | 785 return InternalEncodeSkBitmap(input, |
| 786 discard_transparency, |
| 787 Z_DEFAULT_COMPRESSION, |
| 788 output); |
| 789 } |
| 746 | 790 |
| 747 if (input.empty()) | 791 // static |
| 748 return false; | 792 bool PNGCodec::EncodeA8SkBitmap(const SkBitmap& input, |
| 749 DCHECK_EQ(input.bytesPerPixel(), bbp); | 793 std::vector<unsigned char>* output) { |
| 750 DCHECK_GE(static_cast<int>(input.rowBytes()), input.width() * bbp); | 794 return InternalEncodeSkBitmap(input, |
| 751 | 795 false, |
| 752 SkAutoLockPixels lock_input(input); | 796 Z_DEFAULT_COMPRESSION, |
| 753 return Encode(reinterpret_cast<unsigned char*>(input.getAddr32(0, 0)), | 797 output); |
| 754 FORMAT_SkBitmap, Size(input.width(), input.height()), | |
| 755 static_cast<int>(input.rowBytes()), discard_transparency, | |
| 756 std::vector<Comment>(), output); | |
| 757 } | 798 } |
| 758 | 799 |
| 759 // static | 800 // static |
| 760 bool PNGCodec::FastEncodeBGRASkBitmap(const SkBitmap& input, | 801 bool PNGCodec::FastEncodeBGRASkBitmap(const SkBitmap& input, |
| 761 bool discard_transparency, | 802 bool discard_transparency, |
| 762 std::vector<unsigned char>* output) { | 803 std::vector<unsigned char>* output) { |
| 763 static const int bbp = 4; | 804 return InternalEncodeSkBitmap(input, |
| 764 | 805 discard_transparency, |
| 765 if (input.empty()) | 806 Z_BEST_SPEED, |
| 766 return false; | 807 output); |
| 767 DCHECK_EQ(input.bytesPerPixel(), bbp); | |
| 768 DCHECK_GE(static_cast<int>(input.rowBytes()), input.width() * bbp); | |
| 769 | |
| 770 SkAutoLockPixels lock_input(input); | |
| 771 return EncodeWithCompressionLevel( | |
| 772 reinterpret_cast<unsigned char*>(input.getAddr32(0, 0)), | |
| 773 FORMAT_SkBitmap, Size(input.width(), input.height()), | |
| 774 static_cast<int>(input.rowBytes()), discard_transparency, | |
| 775 std::vector<Comment>(), Z_BEST_SPEED, output); | |
| 776 } | 808 } |
| 777 | 809 |
| 778 PNGCodec::Comment::Comment(const std::string& k, const std::string& t) | 810 PNGCodec::Comment::Comment(const std::string& k, const std::string& t) |
| 779 : key(k), text(t) { | 811 : key(k), text(t) { |
| 780 } | 812 } |
| 781 | 813 |
| 782 PNGCodec::Comment::~Comment() { | 814 PNGCodec::Comment::~Comment() { |
| 783 } | 815 } |
| 784 | 816 |
| 785 } // namespace gfx | 817 } // namespace gfx |
| OLD | NEW |