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

Unified Diff: ui/gfx/codec/png_codec.cc

Issue 136453009: Fix for Issue 331895: Make gesturenav screenshot greyscale (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 11 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 side-by-side diff with in-line comments
Download patch
« ui/gfx/codec/png_codec.h ('K') | « ui/gfx/codec/png_codec.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/gfx/codec/png_codec.cc
diff --git a/ui/gfx/codec/png_codec.cc b/ui/gfx/codec/png_codec.cc
index b3f4345343f0d15a49c0cfc9c759bed662cc4189..25a125d9ec73d4c0174548e48ba12bfdc681f0a2 100644
--- a/ui/gfx/codec/png_codec.cc
+++ b/ui/gfx/codec/png_codec.cc
@@ -18,6 +18,21 @@ namespace gfx {
namespace {
+// Transform coefficients (expressed in 16.16 fixed-point numbers)
+// for RGB into grayscale.
+// Same coefficients as used in png_do_rgb_to_gray() in pngtran.c in libpng
+static const uint32_t RED_TO_GRAY_COEF = 6969; // .212671 * 32768
sadrul 2014/01/15 21:43:06 two spaces before EOL // comments
+static const uint32_t GREEN_TO_GRAY_COEF = 23434; // .715160 * 32768
+static const uint32_t BLUE_TO_GRAY_COEF = 32768 - RED_TO_GRAY_COEF -
+ GREEN_TO_GRAY_COEF;
+
+static inline unsigned char PixelRgbtoGray(unsigned char r, unsigned char b,
+ unsigned char g) {
+ return (RED_TO_GRAY_COEF * r + GREEN_TO_GRAY_COEF * g +
+ BLUE_TO_GRAY_COEF * b) >> 15;
+}
+
+
// Converts BGRA->RGBA and RGBA->BGRA.
void ConvertBetweenBGRAandRGBA(const unsigned char* input, int pixel_width,
unsigned char* output, bool* is_opaque) {
@@ -31,6 +46,32 @@ void ConvertBetweenBGRAandRGBA(const unsigned char* input, int pixel_width,
}
}
+void ConvertBGRAtoGray(const unsigned char* bgra, int pixel_width,
+ unsigned char* gray, bool* is_opaque) {
+ for (int x = 0; x < pixel_width; x++) {
+ const unsigned char* pixel_in = &bgra[x * 4];
+ gray[x] = PixelRgbtoGray(pixel_in[2], pixel_in[1], pixel_in[0]);
+ }
+}
+
+void ConvertBGRAtoGrayAlpha(const unsigned char* bgra, int pixel_width,
+ unsigned char* grayalpha, bool* is_opaque) {
+ for (int x = 0; x < pixel_width; x++) {
+ const unsigned char* pixel_in = &bgra[x * 4];
+ unsigned char* pixel_out = &grayalpha[x * 2];
+ pixel_out[0] = PixelRgbtoGray(pixel_in[2], pixel_in[1], pixel_in[0]);
+ pixel_out[1] = pixel_in[3]; // alpha
+ }
+}
+
+void ConvertRGBtoGray(const unsigned char* rgb, int pixel_width,
+ unsigned char* gray, bool* is_opaque) {
+ for (int x = 0; x < pixel_width; x++) {
+ const unsigned char* pixel_in = &rgb[x * 3];
+ gray[x] = PixelRgbtoGray(pixel_in[0], pixel_in[1], pixel_in[2]);
+ }
+}
+
void ConvertRGBAtoRGB(const unsigned char* rgba, int pixel_width,
unsigned char* rgb, bool* is_opaque) {
for (int x = 0; x < pixel_width; x++) {
@@ -42,6 +83,25 @@ void ConvertRGBAtoRGB(const unsigned char* rgba, int pixel_width,
}
}
+void ConvertRGBAtoGray(const unsigned char* rgba, int pixel_width,
+ unsigned char* gray, bool* is_opaque) {
+ for (int x = 0; x < pixel_width; x++) {
+ const unsigned char* pixel_in = &rgba[x * 4];
+ gray[x] = PixelRgbtoGray(pixel_in[0], pixel_in[1], pixel_in[2]);
+ }
+}
+
+void ConvertRGBAtoGrayAlpha(const unsigned char* rgba, int pixel_width,
+ unsigned char* grayalpha, bool* is_opaque) {
+ for (int x = 0; x < pixel_width; x++) {
+ const unsigned char* pixel_in = &rgba[x * 4];
+ unsigned char* pixel_out = &grayalpha[x * 2];
+ pixel_out[0] = PixelRgbtoGray(pixel_in[0], pixel_in[1], pixel_in[2]);
+ pixel_out[1] = pixel_in[3]; // alpha
+ }
+}
+
+
void ConvertSkiatoRGB(const unsigned char* skia, int pixel_width,
unsigned char* rgb, bool* is_opaque) {
for (int x = 0; x < pixel_width; x++) {
@@ -67,6 +127,48 @@ void ConvertSkiatoRGBA(const unsigned char* skia, int pixel_width,
gfx::ConvertSkiaToRGBA(skia, pixel_width, rgba);
}
+void ConvertSkiatoGray(const unsigned char* skia, int pixel_width,
+ unsigned char* gray, bool* is_opaque) {
+ for (int x = 0; x < pixel_width; x++) {
+ const uint32_t pixel_in = *reinterpret_cast<const uint32_t*>(&skia[x * 4]);
+ unsigned char* pixel_out = &gray[x];
+
+ int alpha = SkGetPackedA32(pixel_in);
+ if (alpha != 0 && alpha != 255) {
+ SkColor unmultiplied = SkUnPreMultiply::PMColorToColor(pixel_in);
+ pixel_out[0] = PixelRgbtoGray(SkColorGetR(unmultiplied),
+ SkColorGetG(unmultiplied),
+ SkColorGetB(unmultiplied));
+ } else {
+ pixel_out[0] = PixelRgbtoGray(SkGetPackedR32(pixel_in),
+ SkGetPackedG32(pixel_in),
+ SkGetPackedB32(pixel_in));
+ }
+ }
+}
+
+void ConvertSkiatoGrayAlpha(const unsigned char* skia, int pixel_width,
+ unsigned char* grayalpha, bool* is_opaque) {
+ for (int x = 0; x < pixel_width; x++) {
+ const uint32_t pixel_in = *reinterpret_cast<const uint32_t*>(&skia[x * 4]);
+ unsigned char* pixel_out = &grayalpha[x * 2];
+
+ int alpha = SkGetPackedA32(pixel_in);
+ if (alpha != 0 && alpha != 255) {
+ SkColor unmultiplied = SkUnPreMultiply::PMColorToColor(pixel_in);
+ pixel_out[0] = PixelRgbtoGray(SkColorGetR(unmultiplied),
+ SkColorGetG(unmultiplied),
+ SkColorGetB(unmultiplied));
+ } else {
+ pixel_out[0] = PixelRgbtoGray(SkGetPackedR32(pixel_in),
+ SkGetPackedG32(pixel_in),
+ SkGetPackedB32(pixel_in));
+ }
+ pixel_out[1] = alpha;
+ }
+}
+
+
} // namespace
// Decoder --------------------------------------------------------------------
@@ -635,6 +737,7 @@ bool EncodeWithCompressionLevel(const unsigned char* input,
const Size& size,
int row_byte_width,
bool discard_transparency,
+ bool discard_color,
const std::vector<PNGCodec::Comment>& comments,
int compression_level,
std::vector<unsigned char>* output) {
@@ -647,46 +750,89 @@ bool EncodeWithCompressionLevel(const unsigned char* input,
switch (format) {
case PNGCodec::FORMAT_RGB:
input_color_components = 3;
- output_color_components = 3;
- png_output_color_type = PNG_COLOR_TYPE_RGB;
+ if (discard_color) {
+ output_color_components = 1;
+ png_output_color_type = PNG_COLOR_TYPE_GRAY;
+ converter = ConvertRGBtoGray;
+ } else {
+ output_color_components = 3;
+ png_output_color_type = PNG_COLOR_TYPE_RGB;
+ converter = NULL;
+ }
break;
case PNGCodec::FORMAT_RGBA:
input_color_components = 4;
if (discard_transparency) {
- output_color_components = 3;
- png_output_color_type = PNG_COLOR_TYPE_RGB;
- converter = ConvertRGBAtoRGB;
+ if (discard_color) {
+ output_color_components = 1;
+ png_output_color_type = PNG_COLOR_TYPE_GRAY;
+ converter = ConvertRGBAtoGray;
+ } else {
+ output_color_components = 3;
+ png_output_color_type = PNG_COLOR_TYPE_RGB;
+ converter = ConvertRGBAtoRGB;
+ }
} else {
- output_color_components = 4;
- png_output_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
- converter = NULL;
+ if (discard_color) {
+ output_color_components = 2;
+ png_output_color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
+ converter = ConvertRGBAtoGrayAlpha;
+ } else {
+ output_color_components = 4;
+ png_output_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
+ converter = NULL;
+ }
}
break;
case PNGCodec::FORMAT_BGRA:
input_color_components = 4;
if (discard_transparency) {
- output_color_components = 3;
- png_output_color_type = PNG_COLOR_TYPE_RGB;
- converter = ConvertBGRAtoRGB;
+ if (discard_color) {
+ output_color_components = 1;
+ png_output_color_type = PNG_COLOR_TYPE_GRAY;
+ converter = ConvertBGRAtoGray;
+ } else {
+ output_color_components = 3;
+ png_output_color_type = PNG_COLOR_TYPE_RGB;
+ converter = ConvertBGRAtoRGB;
+ }
} else {
- output_color_components = 4;
- png_output_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
- converter = ConvertBetweenBGRAandRGBA;
+ if (discard_color) {
+ output_color_components = 2;
+ png_output_color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
+ converter = ConvertBGRAtoGrayAlpha;
+ } else {
+ output_color_components = 4;
+ png_output_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
+ converter = ConvertBetweenBGRAandRGBA;
+ }
}
break;
case PNGCodec::FORMAT_SkBitmap:
input_color_components = 4;
if (discard_transparency) {
- output_color_components = 3;
- png_output_color_type = PNG_COLOR_TYPE_RGB;
- converter = ConvertSkiatoRGB;
+ if (discard_color) {
+ output_color_components = 1;
+ png_output_color_type = PNG_COLOR_TYPE_GRAY;
+ converter = ConvertSkiatoGray;
+ } else {
+ output_color_components = 3;
+ png_output_color_type = PNG_COLOR_TYPE_RGB;
+ converter = ConvertSkiatoRGB;
+ }
} else {
- output_color_components = 4;
- png_output_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
- converter = ConvertSkiatoRGBA;
+ if (discard_color) {
+ output_color_components = 2;
+ png_output_color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
+ converter = ConvertSkiatoGrayAlpha;
+ } else {
+ output_color_components = 4;
+ png_output_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
+ converter = ConvertSkiatoRGBA;
+ }
sadrul 2014/01/15 21:43:06 I wonder if this could somehow be simplified, e.g.
}
break;
@@ -727,12 +873,14 @@ bool PNGCodec::Encode(const unsigned char* input, ColorFormat format,
const Size& size, int row_byte_width,
bool discard_transparency,
const std::vector<Comment>& comments,
- std::vector<unsigned char>* output) {
+ std::vector<unsigned char>* output,
+ bool discard_color) {
return EncodeWithCompressionLevel(input,
format,
size,
row_byte_width,
discard_transparency,
+ discard_color,
comments,
Z_DEFAULT_COMPRESSION,
output);
@@ -741,7 +889,8 @@ bool PNGCodec::Encode(const unsigned char* input, ColorFormat format,
// static
bool PNGCodec::EncodeBGRASkBitmap(const SkBitmap& input,
bool discard_transparency,
- std::vector<unsigned char>* output) {
+ std::vector<unsigned char>* output,
+ bool discard_color) {
static const int bbp = 4;
if (input.empty())
@@ -753,13 +902,14 @@ bool PNGCodec::EncodeBGRASkBitmap(const SkBitmap& input,
return Encode(reinterpret_cast<unsigned char*>(input.getAddr32(0, 0)),
FORMAT_SkBitmap, Size(input.width(), input.height()),
static_cast<int>(input.rowBytes()), discard_transparency,
- std::vector<Comment>(), output);
+ std::vector<Comment>(), output, discard_color);
}
// static
bool PNGCodec::FastEncodeBGRASkBitmap(const SkBitmap& input,
bool discard_transparency,
- std::vector<unsigned char>* output) {
+ std::vector<unsigned char>* output,
+ bool discard_color) {
static const int bbp = 4;
if (input.empty())
@@ -772,7 +922,7 @@ bool PNGCodec::FastEncodeBGRASkBitmap(const SkBitmap& input,
reinterpret_cast<unsigned char*>(input.getAddr32(0, 0)),
FORMAT_SkBitmap, Size(input.width(), input.height()),
static_cast<int>(input.rowBytes()), discard_transparency,
- std::vector<Comment>(), Z_BEST_SPEED, output);
+ discard_color, std::vector<Comment>(), Z_BEST_SPEED, output);
}
PNGCodec::Comment::Comment(const std::string& k, const std::string& t)
« ui/gfx/codec/png_codec.h ('K') | « ui/gfx/codec/png_codec.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698