Chromium Code Reviews| 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" |
| 11 #include "third_party/skia/include/core/SkColorPriv.h" | 11 #include "third_party/skia/include/core/SkColorPriv.h" |
| 12 #include "third_party/skia/include/core/SkUnPreMultiply.h" | 12 #include "third_party/skia/include/core/SkUnPreMultiply.h" |
| 13 #include "third_party/zlib/zlib.h" | 13 #include "third_party/zlib/zlib.h" |
| 14 #include "ui/gfx/size.h" | 14 #include "ui/gfx/size.h" |
| 15 #include "ui/gfx/skia_util.h" | 15 #include "ui/gfx/skia_util.h" |
| 16 | 16 |
| 17 namespace gfx { | 17 namespace gfx { |
| 18 | 18 |
| 19 namespace { | 19 namespace { |
| 20 | 20 |
| 21 // Transform coefficients (expressed in 16.16 fixed-point numbers) | |
| 22 // for RGB into grayscale. | |
| 23 // Same coefficients as used in png_do_rgb_to_gray() in pngtran.c in libpng | |
| 24 static const uint32_t RED_TO_GRAY_COEF = 6969; // .212671 * 32768 | |
|
sadrul
2014/01/15 21:43:06
two spaces before EOL // comments
| |
| 25 static const uint32_t GREEN_TO_GRAY_COEF = 23434; // .715160 * 32768 | |
| 26 static const uint32_t BLUE_TO_GRAY_COEF = 32768 - RED_TO_GRAY_COEF - | |
| 27 GREEN_TO_GRAY_COEF; | |
| 28 | |
| 29 static inline unsigned char PixelRgbtoGray(unsigned char r, unsigned char b, | |
| 30 unsigned char g) { | |
| 31 return (RED_TO_GRAY_COEF * r + GREEN_TO_GRAY_COEF * g + | |
| 32 BLUE_TO_GRAY_COEF * b) >> 15; | |
| 33 } | |
| 34 | |
| 35 | |
| 21 // Converts BGRA->RGBA and RGBA->BGRA. | 36 // Converts BGRA->RGBA and RGBA->BGRA. |
| 22 void ConvertBetweenBGRAandRGBA(const unsigned char* input, int pixel_width, | 37 void ConvertBetweenBGRAandRGBA(const unsigned char* input, int pixel_width, |
| 23 unsigned char* output, bool* is_opaque) { | 38 unsigned char* output, bool* is_opaque) { |
| 24 for (int x = 0; x < pixel_width; x++) { | 39 for (int x = 0; x < pixel_width; x++) { |
| 25 const unsigned char* pixel_in = &input[x * 4]; | 40 const unsigned char* pixel_in = &input[x * 4]; |
| 26 unsigned char* pixel_out = &output[x * 4]; | 41 unsigned char* pixel_out = &output[x * 4]; |
| 27 pixel_out[0] = pixel_in[2]; | 42 pixel_out[0] = pixel_in[2]; |
| 28 pixel_out[1] = pixel_in[1]; | 43 pixel_out[1] = pixel_in[1]; |
| 29 pixel_out[2] = pixel_in[0]; | 44 pixel_out[2] = pixel_in[0]; |
| 30 pixel_out[3] = pixel_in[3]; | 45 pixel_out[3] = pixel_in[3]; |
| 31 } | 46 } |
| 32 } | 47 } |
| 33 | 48 |
| 49 void ConvertBGRAtoGray(const unsigned char* bgra, int pixel_width, | |
| 50 unsigned char* gray, bool* is_opaque) { | |
| 51 for (int x = 0; x < pixel_width; x++) { | |
| 52 const unsigned char* pixel_in = &bgra[x * 4]; | |
| 53 gray[x] = PixelRgbtoGray(pixel_in[2], pixel_in[1], pixel_in[0]); | |
| 54 } | |
| 55 } | |
| 56 | |
| 57 void ConvertBGRAtoGrayAlpha(const unsigned char* bgra, int pixel_width, | |
| 58 unsigned char* grayalpha, bool* is_opaque) { | |
| 59 for (int x = 0; x < pixel_width; x++) { | |
| 60 const unsigned char* pixel_in = &bgra[x * 4]; | |
| 61 unsigned char* pixel_out = &grayalpha[x * 2]; | |
| 62 pixel_out[0] = PixelRgbtoGray(pixel_in[2], pixel_in[1], pixel_in[0]); | |
| 63 pixel_out[1] = pixel_in[3]; // alpha | |
| 64 } | |
| 65 } | |
| 66 | |
| 67 void ConvertRGBtoGray(const unsigned char* rgb, int pixel_width, | |
| 68 unsigned char* gray, bool* is_opaque) { | |
| 69 for (int x = 0; x < pixel_width; x++) { | |
| 70 const unsigned char* pixel_in = &rgb[x * 3]; | |
| 71 gray[x] = PixelRgbtoGray(pixel_in[0], pixel_in[1], pixel_in[2]); | |
| 72 } | |
| 73 } | |
| 74 | |
| 34 void ConvertRGBAtoRGB(const unsigned char* rgba, int pixel_width, | 75 void ConvertRGBAtoRGB(const unsigned char* rgba, int pixel_width, |
| 35 unsigned char* rgb, bool* is_opaque) { | 76 unsigned char* rgb, bool* is_opaque) { |
| 36 for (int x = 0; x < pixel_width; x++) { | 77 for (int x = 0; x < pixel_width; x++) { |
| 37 const unsigned char* pixel_in = &rgba[x * 4]; | 78 const unsigned char* pixel_in = &rgba[x * 4]; |
| 38 unsigned char* pixel_out = &rgb[x * 3]; | 79 unsigned char* pixel_out = &rgb[x * 3]; |
| 39 pixel_out[0] = pixel_in[0]; | 80 pixel_out[0] = pixel_in[0]; |
| 40 pixel_out[1] = pixel_in[1]; | 81 pixel_out[1] = pixel_in[1]; |
| 41 pixel_out[2] = pixel_in[2]; | 82 pixel_out[2] = pixel_in[2]; |
| 42 } | 83 } |
| 43 } | 84 } |
| 44 | 85 |
| 86 void ConvertRGBAtoGray(const unsigned char* rgba, int pixel_width, | |
| 87 unsigned char* gray, bool* is_opaque) { | |
| 88 for (int x = 0; x < pixel_width; x++) { | |
| 89 const unsigned char* pixel_in = &rgba[x * 4]; | |
| 90 gray[x] = PixelRgbtoGray(pixel_in[0], pixel_in[1], pixel_in[2]); | |
| 91 } | |
| 92 } | |
| 93 | |
| 94 void ConvertRGBAtoGrayAlpha(const unsigned char* rgba, int pixel_width, | |
| 95 unsigned char* grayalpha, bool* is_opaque) { | |
| 96 for (int x = 0; x < pixel_width; x++) { | |
| 97 const unsigned char* pixel_in = &rgba[x * 4]; | |
| 98 unsigned char* pixel_out = &grayalpha[x * 2]; | |
| 99 pixel_out[0] = PixelRgbtoGray(pixel_in[0], pixel_in[1], pixel_in[2]); | |
| 100 pixel_out[1] = pixel_in[3]; // alpha | |
| 101 } | |
| 102 } | |
| 103 | |
| 104 | |
| 45 void ConvertSkiatoRGB(const unsigned char* skia, int pixel_width, | 105 void ConvertSkiatoRGB(const unsigned char* skia, int pixel_width, |
| 46 unsigned char* rgb, bool* is_opaque) { | 106 unsigned char* rgb, bool* is_opaque) { |
| 47 for (int x = 0; x < pixel_width; x++) { | 107 for (int x = 0; x < pixel_width; x++) { |
| 48 const uint32_t pixel_in = *reinterpret_cast<const uint32_t*>(&skia[x * 4]); | 108 const uint32_t pixel_in = *reinterpret_cast<const uint32_t*>(&skia[x * 4]); |
| 49 unsigned char* pixel_out = &rgb[x * 3]; | 109 unsigned char* pixel_out = &rgb[x * 3]; |
| 50 | 110 |
| 51 int alpha = SkGetPackedA32(pixel_in); | 111 int alpha = SkGetPackedA32(pixel_in); |
| 52 if (alpha != 0 && alpha != 255) { | 112 if (alpha != 0 && alpha != 255) { |
| 53 SkColor unmultiplied = SkUnPreMultiply::PMColorToColor(pixel_in); | 113 SkColor unmultiplied = SkUnPreMultiply::PMColorToColor(pixel_in); |
| 54 pixel_out[0] = SkColorGetR(unmultiplied); | 114 pixel_out[0] = SkColorGetR(unmultiplied); |
| 55 pixel_out[1] = SkColorGetG(unmultiplied); | 115 pixel_out[1] = SkColorGetG(unmultiplied); |
| 56 pixel_out[2] = SkColorGetB(unmultiplied); | 116 pixel_out[2] = SkColorGetB(unmultiplied); |
| 57 } else { | 117 } else { |
| 58 pixel_out[0] = SkGetPackedR32(pixel_in); | 118 pixel_out[0] = SkGetPackedR32(pixel_in); |
| 59 pixel_out[1] = SkGetPackedG32(pixel_in); | 119 pixel_out[1] = SkGetPackedG32(pixel_in); |
| 60 pixel_out[2] = SkGetPackedB32(pixel_in); | 120 pixel_out[2] = SkGetPackedB32(pixel_in); |
| 61 } | 121 } |
| 62 } | 122 } |
| 63 } | 123 } |
| 64 | 124 |
| 65 void ConvertSkiatoRGBA(const unsigned char* skia, int pixel_width, | 125 void ConvertSkiatoRGBA(const unsigned char* skia, int pixel_width, |
| 66 unsigned char* rgba, bool* is_opaque) { | 126 unsigned char* rgba, bool* is_opaque) { |
| 67 gfx::ConvertSkiaToRGBA(skia, pixel_width, rgba); | 127 gfx::ConvertSkiaToRGBA(skia, pixel_width, rgba); |
| 68 } | 128 } |
| 69 | 129 |
| 130 void ConvertSkiatoGray(const unsigned char* skia, int pixel_width, | |
| 131 unsigned char* gray, bool* is_opaque) { | |
| 132 for (int x = 0; x < pixel_width; x++) { | |
| 133 const uint32_t pixel_in = *reinterpret_cast<const uint32_t*>(&skia[x * 4]); | |
| 134 unsigned char* pixel_out = &gray[x]; | |
| 135 | |
| 136 int alpha = SkGetPackedA32(pixel_in); | |
| 137 if (alpha != 0 && alpha != 255) { | |
| 138 SkColor unmultiplied = SkUnPreMultiply::PMColorToColor(pixel_in); | |
| 139 pixel_out[0] = PixelRgbtoGray(SkColorGetR(unmultiplied), | |
| 140 SkColorGetG(unmultiplied), | |
| 141 SkColorGetB(unmultiplied)); | |
| 142 } else { | |
| 143 pixel_out[0] = PixelRgbtoGray(SkGetPackedR32(pixel_in), | |
| 144 SkGetPackedG32(pixel_in), | |
| 145 SkGetPackedB32(pixel_in)); | |
| 146 } | |
| 147 } | |
| 148 } | |
| 149 | |
| 150 void ConvertSkiatoGrayAlpha(const unsigned char* skia, int pixel_width, | |
| 151 unsigned char* grayalpha, bool* is_opaque) { | |
| 152 for (int x = 0; x < pixel_width; x++) { | |
| 153 const uint32_t pixel_in = *reinterpret_cast<const uint32_t*>(&skia[x * 4]); | |
| 154 unsigned char* pixel_out = &grayalpha[x * 2]; | |
| 155 | |
| 156 int alpha = SkGetPackedA32(pixel_in); | |
| 157 if (alpha != 0 && alpha != 255) { | |
| 158 SkColor unmultiplied = SkUnPreMultiply::PMColorToColor(pixel_in); | |
| 159 pixel_out[0] = PixelRgbtoGray(SkColorGetR(unmultiplied), | |
| 160 SkColorGetG(unmultiplied), | |
| 161 SkColorGetB(unmultiplied)); | |
| 162 } else { | |
| 163 pixel_out[0] = PixelRgbtoGray(SkGetPackedR32(pixel_in), | |
| 164 SkGetPackedG32(pixel_in), | |
| 165 SkGetPackedB32(pixel_in)); | |
| 166 } | |
| 167 pixel_out[1] = alpha; | |
| 168 } | |
| 169 } | |
| 170 | |
| 171 | |
| 70 } // namespace | 172 } // namespace |
| 71 | 173 |
| 72 // Decoder -------------------------------------------------------------------- | 174 // Decoder -------------------------------------------------------------------- |
| 73 // | 175 // |
| 74 // This code is based on WebKit libpng interface (PNGImageDecoder), which is | 176 // This code is based on WebKit libpng interface (PNGImageDecoder), which is |
| 75 // in turn based on the Mozilla png decoder. | 177 // in turn based on the Mozilla png decoder. |
| 76 | 178 |
| 77 namespace { | 179 namespace { |
| 78 | 180 |
| 79 // Gamma constants: We assume we're on Windows which uses a gamma of 2.2. | 181 // Gamma constants: We assume we're on Windows which uses a gamma of 2.2. |
| (...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 628 | 730 |
| 629 png_write_end(png_ptr, info_ptr); | 731 png_write_end(png_ptr, info_ptr); |
| 630 return true; | 732 return true; |
| 631 } | 733 } |
| 632 | 734 |
| 633 bool EncodeWithCompressionLevel(const unsigned char* input, | 735 bool EncodeWithCompressionLevel(const unsigned char* input, |
| 634 PNGCodec::ColorFormat format, | 736 PNGCodec::ColorFormat format, |
| 635 const Size& size, | 737 const Size& size, |
| 636 int row_byte_width, | 738 int row_byte_width, |
| 637 bool discard_transparency, | 739 bool discard_transparency, |
| 740 bool discard_color, | |
| 638 const std::vector<PNGCodec::Comment>& comments, | 741 const std::vector<PNGCodec::Comment>& comments, |
| 639 int compression_level, | 742 int compression_level, |
| 640 std::vector<unsigned char>* output) { | 743 std::vector<unsigned char>* output) { |
| 641 // Run to convert an input row into the output row format, NULL means no | 744 // Run to convert an input row into the output row format, NULL means no |
| 642 // conversion is necessary. | 745 // conversion is necessary. |
| 643 FormatConverter converter = NULL; | 746 FormatConverter converter = NULL; |
| 644 | 747 |
| 645 int input_color_components, output_color_components; | 748 int input_color_components, output_color_components; |
| 646 int png_output_color_type; | 749 int png_output_color_type; |
| 647 switch (format) { | 750 switch (format) { |
| 648 case PNGCodec::FORMAT_RGB: | 751 case PNGCodec::FORMAT_RGB: |
| 649 input_color_components = 3; | 752 input_color_components = 3; |
| 650 output_color_components = 3; | 753 if (discard_color) { |
| 651 png_output_color_type = PNG_COLOR_TYPE_RGB; | 754 output_color_components = 1; |
| 755 png_output_color_type = PNG_COLOR_TYPE_GRAY; | |
| 756 converter = ConvertRGBtoGray; | |
| 757 } else { | |
| 758 output_color_components = 3; | |
| 759 png_output_color_type = PNG_COLOR_TYPE_RGB; | |
| 760 converter = NULL; | |
| 761 } | |
| 652 break; | 762 break; |
| 653 | 763 |
| 654 case PNGCodec::FORMAT_RGBA: | 764 case PNGCodec::FORMAT_RGBA: |
| 655 input_color_components = 4; | 765 input_color_components = 4; |
| 656 if (discard_transparency) { | 766 if (discard_transparency) { |
| 657 output_color_components = 3; | 767 if (discard_color) { |
| 658 png_output_color_type = PNG_COLOR_TYPE_RGB; | 768 output_color_components = 1; |
| 659 converter = ConvertRGBAtoRGB; | 769 png_output_color_type = PNG_COLOR_TYPE_GRAY; |
| 770 converter = ConvertRGBAtoGray; | |
| 771 } else { | |
| 772 output_color_components = 3; | |
| 773 png_output_color_type = PNG_COLOR_TYPE_RGB; | |
| 774 converter = ConvertRGBAtoRGB; | |
| 775 } | |
| 660 } else { | 776 } else { |
| 661 output_color_components = 4; | 777 if (discard_color) { |
| 662 png_output_color_type = PNG_COLOR_TYPE_RGB_ALPHA; | 778 output_color_components = 2; |
| 663 converter = NULL; | 779 png_output_color_type = PNG_COLOR_TYPE_GRAY_ALPHA; |
| 780 converter = ConvertRGBAtoGrayAlpha; | |
| 781 } else { | |
| 782 output_color_components = 4; | |
| 783 png_output_color_type = PNG_COLOR_TYPE_RGB_ALPHA; | |
| 784 converter = NULL; | |
| 785 } | |
| 664 } | 786 } |
| 665 break; | 787 break; |
| 666 | 788 |
| 667 case PNGCodec::FORMAT_BGRA: | 789 case PNGCodec::FORMAT_BGRA: |
| 668 input_color_components = 4; | 790 input_color_components = 4; |
| 669 if (discard_transparency) { | 791 if (discard_transparency) { |
| 670 output_color_components = 3; | 792 if (discard_color) { |
| 671 png_output_color_type = PNG_COLOR_TYPE_RGB; | 793 output_color_components = 1; |
| 672 converter = ConvertBGRAtoRGB; | 794 png_output_color_type = PNG_COLOR_TYPE_GRAY; |
| 795 converter = ConvertBGRAtoGray; | |
| 796 } else { | |
| 797 output_color_components = 3; | |
| 798 png_output_color_type = PNG_COLOR_TYPE_RGB; | |
| 799 converter = ConvertBGRAtoRGB; | |
| 800 } | |
| 673 } else { | 801 } else { |
| 674 output_color_components = 4; | 802 if (discard_color) { |
| 675 png_output_color_type = PNG_COLOR_TYPE_RGB_ALPHA; | 803 output_color_components = 2; |
| 676 converter = ConvertBetweenBGRAandRGBA; | 804 png_output_color_type = PNG_COLOR_TYPE_GRAY_ALPHA; |
| 805 converter = ConvertBGRAtoGrayAlpha; | |
| 806 } else { | |
| 807 output_color_components = 4; | |
| 808 png_output_color_type = PNG_COLOR_TYPE_RGB_ALPHA; | |
| 809 converter = ConvertBetweenBGRAandRGBA; | |
| 810 } | |
| 677 } | 811 } |
| 678 break; | 812 break; |
| 679 | 813 |
| 680 case PNGCodec::FORMAT_SkBitmap: | 814 case PNGCodec::FORMAT_SkBitmap: |
| 681 input_color_components = 4; | 815 input_color_components = 4; |
| 682 if (discard_transparency) { | 816 if (discard_transparency) { |
| 683 output_color_components = 3; | 817 if (discard_color) { |
| 684 png_output_color_type = PNG_COLOR_TYPE_RGB; | 818 output_color_components = 1; |
| 685 converter = ConvertSkiatoRGB; | 819 png_output_color_type = PNG_COLOR_TYPE_GRAY; |
| 820 converter = ConvertSkiatoGray; | |
| 821 } else { | |
| 822 output_color_components = 3; | |
| 823 png_output_color_type = PNG_COLOR_TYPE_RGB; | |
| 824 converter = ConvertSkiatoRGB; | |
| 825 } | |
| 686 } else { | 826 } else { |
| 687 output_color_components = 4; | 827 if (discard_color) { |
| 688 png_output_color_type = PNG_COLOR_TYPE_RGB_ALPHA; | 828 output_color_components = 2; |
| 689 converter = ConvertSkiatoRGBA; | 829 png_output_color_type = PNG_COLOR_TYPE_GRAY_ALPHA; |
| 830 converter = ConvertSkiatoGrayAlpha; | |
| 831 } else { | |
| 832 output_color_components = 4; | |
| 833 png_output_color_type = PNG_COLOR_TYPE_RGB_ALPHA; | |
| 834 converter = ConvertSkiatoRGBA; | |
| 835 } | |
|
sadrul
2014/01/15 21:43:06
I wonder if this could somehow be simplified, e.g.
| |
| 690 } | 836 } |
| 691 break; | 837 break; |
| 692 | 838 |
| 693 default: | 839 default: |
| 694 NOTREACHED() << "Unknown pixel format"; | 840 NOTREACHED() << "Unknown pixel format"; |
| 695 return false; | 841 return false; |
| 696 } | 842 } |
| 697 | 843 |
| 698 // Row stride should be at least as long as the length of the data. | 844 // Row stride should be at least as long as the length of the data. |
| 699 DCHECK(input_color_components * size.width() <= row_byte_width); | 845 DCHECK(input_color_components * size.width() <= row_byte_width); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 720 } | 866 } |
| 721 | 867 |
| 722 | 868 |
| 723 } // namespace | 869 } // namespace |
| 724 | 870 |
| 725 // static | 871 // static |
| 726 bool PNGCodec::Encode(const unsigned char* input, ColorFormat format, | 872 bool PNGCodec::Encode(const unsigned char* input, ColorFormat format, |
| 727 const Size& size, int row_byte_width, | 873 const Size& size, int row_byte_width, |
| 728 bool discard_transparency, | 874 bool discard_transparency, |
| 729 const std::vector<Comment>& comments, | 875 const std::vector<Comment>& comments, |
| 730 std::vector<unsigned char>* output) { | 876 std::vector<unsigned char>* output, |
| 877 bool discard_color) { | |
| 731 return EncodeWithCompressionLevel(input, | 878 return EncodeWithCompressionLevel(input, |
| 732 format, | 879 format, |
| 733 size, | 880 size, |
| 734 row_byte_width, | 881 row_byte_width, |
| 735 discard_transparency, | 882 discard_transparency, |
| 883 discard_color, | |
| 736 comments, | 884 comments, |
| 737 Z_DEFAULT_COMPRESSION, | 885 Z_DEFAULT_COMPRESSION, |
| 738 output); | 886 output); |
| 739 } | 887 } |
| 740 | 888 |
| 741 // static | 889 // static |
| 742 bool PNGCodec::EncodeBGRASkBitmap(const SkBitmap& input, | 890 bool PNGCodec::EncodeBGRASkBitmap(const SkBitmap& input, |
| 743 bool discard_transparency, | 891 bool discard_transparency, |
| 744 std::vector<unsigned char>* output) { | 892 std::vector<unsigned char>* output, |
| 893 bool discard_color) { | |
| 745 static const int bbp = 4; | 894 static const int bbp = 4; |
| 746 | 895 |
| 747 if (input.empty()) | 896 if (input.empty()) |
| 748 return false; | 897 return false; |
| 749 DCHECK_EQ(input.bytesPerPixel(), bbp); | 898 DCHECK_EQ(input.bytesPerPixel(), bbp); |
| 750 DCHECK_GE(static_cast<int>(input.rowBytes()), input.width() * bbp); | 899 DCHECK_GE(static_cast<int>(input.rowBytes()), input.width() * bbp); |
| 751 | 900 |
| 752 SkAutoLockPixels lock_input(input); | 901 SkAutoLockPixels lock_input(input); |
| 753 return Encode(reinterpret_cast<unsigned char*>(input.getAddr32(0, 0)), | 902 return Encode(reinterpret_cast<unsigned char*>(input.getAddr32(0, 0)), |
| 754 FORMAT_SkBitmap, Size(input.width(), input.height()), | 903 FORMAT_SkBitmap, Size(input.width(), input.height()), |
| 755 static_cast<int>(input.rowBytes()), discard_transparency, | 904 static_cast<int>(input.rowBytes()), discard_transparency, |
| 756 std::vector<Comment>(), output); | 905 std::vector<Comment>(), output, discard_color); |
| 757 } | 906 } |
| 758 | 907 |
| 759 // static | 908 // static |
| 760 bool PNGCodec::FastEncodeBGRASkBitmap(const SkBitmap& input, | 909 bool PNGCodec::FastEncodeBGRASkBitmap(const SkBitmap& input, |
| 761 bool discard_transparency, | 910 bool discard_transparency, |
| 762 std::vector<unsigned char>* output) { | 911 std::vector<unsigned char>* output, |
| 912 bool discard_color) { | |
| 763 static const int bbp = 4; | 913 static const int bbp = 4; |
| 764 | 914 |
| 765 if (input.empty()) | 915 if (input.empty()) |
| 766 return false; | 916 return false; |
| 767 DCHECK_EQ(input.bytesPerPixel(), bbp); | 917 DCHECK_EQ(input.bytesPerPixel(), bbp); |
| 768 DCHECK_GE(static_cast<int>(input.rowBytes()), input.width() * bbp); | 918 DCHECK_GE(static_cast<int>(input.rowBytes()), input.width() * bbp); |
| 769 | 919 |
| 770 SkAutoLockPixels lock_input(input); | 920 SkAutoLockPixels lock_input(input); |
| 771 return EncodeWithCompressionLevel( | 921 return EncodeWithCompressionLevel( |
| 772 reinterpret_cast<unsigned char*>(input.getAddr32(0, 0)), | 922 reinterpret_cast<unsigned char*>(input.getAddr32(0, 0)), |
| 773 FORMAT_SkBitmap, Size(input.width(), input.height()), | 923 FORMAT_SkBitmap, Size(input.width(), input.height()), |
| 774 static_cast<int>(input.rowBytes()), discard_transparency, | 924 static_cast<int>(input.rowBytes()), discard_transparency, |
| 775 std::vector<Comment>(), Z_BEST_SPEED, output); | 925 discard_color, std::vector<Comment>(), Z_BEST_SPEED, output); |
| 776 } | 926 } |
| 777 | 927 |
| 778 PNGCodec::Comment::Comment(const std::string& k, const std::string& t) | 928 PNGCodec::Comment::Comment(const std::string& k, const std::string& t) |
| 779 : key(k), text(t) { | 929 : key(k), text(t) { |
| 780 } | 930 } |
| 781 | 931 |
| 782 PNGCodec::Comment::~Comment() { | 932 PNGCodec::Comment::~Comment() { |
| 783 } | 933 } |
| 784 | 934 |
| 785 } // namespace gfx | 935 } // namespace gfx |
| OLD | NEW |