diff options
author | John Firebaugh <john.firebaugh@gmail.com> | 2015-11-23 14:17:40 -0800 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2015-11-25 15:57:36 -0800 |
commit | f3d6f68106e60ac0d697202a8e32fa1466d38151 (patch) | |
tree | c0ce3fc1b89d568bd792ba9ea0a4136263b00f48 | |
parent | 0c1e378bc9555f6cf826bb38b1a36fa742f8ce9b (diff) | |
download | qtlocation-mapboxgl-f3d6f68106e60ac0d697202a8e32fa1466d38151.tar.gz |
[core] Always manually premultiply libpng output
It appears to be the only way to get the results we want in all cases.
-rw-r--r-- | platform/default/png_reader.cpp | 26 | ||||
-rw-r--r-- | src/mbgl/util/premultiply.cpp | 30 | ||||
-rw-r--r-- | src/mbgl/util/premultiply.hpp | 14 |
3 files changed, 47 insertions, 23 deletions
diff --git a/platform/default/png_reader.cpp b/platform/default/png_reader.cpp index 7577d9725c..2b9bbbeb46 100644 --- a/platform/default/png_reader.cpp +++ b/platform/default/png_reader.cpp @@ -1,4 +1,5 @@ #include <mbgl/util/image.hpp> +#include <mbgl/util/premultiply.hpp> #include <mbgl/platform/log.hpp> #pragma GCC diagnostic push @@ -88,7 +89,7 @@ PremultipliedImage decodePNG(const uint8_t* data, size_t size) { int color_type = 0; png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 0, 0, 0); - PremultipliedImage image { width, height }; + UnassociatedImage image { width, height }; if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_expand(png_ptr); @@ -108,14 +109,6 @@ PremultipliedImage decodePNG(const uint8_t* data, size_t size) { png_set_add_alpha(png_ptr, 0xff, PNG_FILLER_AFTER); - double gamma; - if (png_get_gAMA(png_ptr, info_ptr, &gamma)) - png_set_gamma(png_ptr, 2.2, gamma); - -#ifdef PNG_ALPHA_PREMULTIPLIED - png_set_alpha_mode(png_ptr, PNG_ALPHA_PREMULTIPLIED, PNG_GAMMA_LINEAR); -#endif - if (png_get_interlace_type(png_ptr,info_ptr) == PNG_INTERLACE_ADAM7) { png_set_interlace_handling(png_ptr); // FIXME: libpng bug? // according to docs png_read_image @@ -132,22 +125,9 @@ PremultipliedImage decodePNG(const uint8_t* data, size_t size) { rows[row] = image.data.get() + row * width * 4; png_read_image(png_ptr, rows.get()); -#ifndef PNG_ALPHA_PREMULTIPLIED - // Manually premultiply the image if libpng didn't do it for us. - for (unsigned row = 0; row < height_; ++row) { - for (unsigned x = 0; x < width_; x++) { - png_byte* ptr = &(rows[row][x * 4]); - const float a = ptr[3] / 255.0f; - ptr[0] *= a; - ptr[1] *= a; - ptr[2] *= a; - } - } -#endif - png_read_end(png_ptr, 0); - return image; + return util::premultiply(std::move(image)); } } diff --git a/src/mbgl/util/premultiply.cpp b/src/mbgl/util/premultiply.cpp new file mode 100644 index 0000000000..3ee5a1e129 --- /dev/null +++ b/src/mbgl/util/premultiply.cpp @@ -0,0 +1,30 @@ +#include <mbgl/util/premultiply.hpp> + +#include <cmath> + +namespace mbgl { +namespace util { + +PremultipliedImage premultiply(UnassociatedImage&& src) { + PremultipliedImage dst; + + dst.width = src.width; + dst.height = src.height; + dst.data = std::move(src.data); + + uint8_t* data = dst.data.get(); + for (size_t i = 0; i < dst.size(); i += 4) { + uint8_t& r = data[i + 0]; + uint8_t& g = data[i + 1]; + uint8_t& b = data[i + 2]; + uint8_t& a = data[i + 3]; + r = (r * a + 127) / 255; + g = (g * a + 127) / 255; + b = (b * a + 127) / 255; + } + + return std::move(dst); +} + +} +} diff --git a/src/mbgl/util/premultiply.hpp b/src/mbgl/util/premultiply.hpp new file mode 100644 index 0000000000..9d9dcc6468 --- /dev/null +++ b/src/mbgl/util/premultiply.hpp @@ -0,0 +1,14 @@ +#ifndef MBGL_UTIL_PREMULTIPLY +#define MBGL_UTIL_PREMULTIPLY + +#include <mbgl/util/image.hpp> + +namespace mbgl { +namespace util { + +PremultipliedImage premultiply(UnassociatedImage&&); + +} +} + +#endif |