From 9cd9065031f7d2af62e437f2b32b44207484baca Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Wed, 20 Jan 2016 00:07:04 +0200 Subject: [PATCH] Revert "Revert WebP support due to broken builds" This reverts commit 6709bdcacd5a45a10b554f3f225206c9494e5e43. There was an issue with the script that removes '-lwebp' from WebP linker flags, since we're statically linking. This is now fixed. --- configure | 1 + gyp/platform-linux.gypi | 4 ++++ include/mbgl/util/image.hpp | 5 +++++ platform/default/image.cpp | 20 +++++++++++++++++--- platform/default/webp_reader.cpp | 27 +++++++++++++++++++++++++++ platform/linux/scripts/configure.sh | 1 + src/mbgl/util/mapbox.cpp | 6 ++++++ test/fixtures/image/tile.webp | Bin 0 -> 8916 bytes test/miscellaneous/image.cpp | 8 ++++++++ test/miscellaneous/mapbox.cpp | 7 +++++++ 10 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 platform/default/webp_reader.cpp create mode 100644 test/fixtures/image/tile.webp diff --git a/configure b/configure index d8ccc0b19..180d03516 100755 --- a/configure +++ b/configure @@ -105,6 +105,7 @@ print_flags variant static_libs cflags ldflags print_flags rapidjson static_libs cflags ldflags print_flags gtest static_libs cflags ldflags print_flags pixelmatch static_libs cflags ldflags +print_flags webp static_libs cflags ldflags CONFIG+=" } } diff --git a/gyp/platform-linux.gypi b/gyp/platform-linux.gypi index 22dc452f3..d43915863 100644 --- a/gyp/platform-linux.gypi +++ b/gyp/platform-linux.gypi @@ -17,6 +17,7 @@ '../platform/default/application_root.cpp', '../platform/default/thread.cpp', '../platform/default/image.cpp', + '../platform/default/webp_reader.cpp', '../platform/default/png_reader.cpp', '../platform/default/jpeg_reader.cpp', '../platform/default/timer.cpp', @@ -35,6 +36,7 @@ '<@(nunicode_cflags)', '<@(boost_cflags)', '<@(sqlite_cflags)', + '<@(webp_cflags)', ], 'ldflags': [ '<@(libpng_ldflags)', @@ -43,6 +45,7 @@ '<@(nunicode_ldflags)', '<@(sqlite_ldflags)', '<@(zlib_ldflags)', + '<@(webp_ldflags)', ], 'libraries': [ '<@(libpng_static_libs)', @@ -51,6 +54,7 @@ '<@(nunicode_static_libs)', '<@(sqlite_static_libs)', '<@(zlib_static_libs)', + '<@(webp_static_libs)', ], }, diff --git a/include/mbgl/util/image.hpp b/include/mbgl/util/image.hpp index fde42c7c5..7927b777e 100644 --- a/include/mbgl/util/image.hpp +++ b/include/mbgl/util/image.hpp @@ -21,6 +21,11 @@ public: height(h), data(std::make_unique(size())) {} + Image(size_t w, size_t h, std::unique_ptr data_) + : width(w), + height(h), + data(std::move(data_)) {} + size_t stride() const { return width * 4; } size_t size() const { return width * height * 4; } diff --git a/platform/default/image.cpp b/platform/default/image.cpp index bf8071af5..71fb5414b 100644 --- a/platform/default/image.cpp +++ b/platform/default/image.cpp @@ -70,6 +70,10 @@ std::string encodePNG(const PremultipliedImage& pre) { return result; } +#if !defined(__ANDROID__) && !defined(__APPLE__) +PremultipliedImage decodeWebP(const uint8_t*, size_t); +#endif // !defined(__ANDROID__) && !defined(__APPLE__) + PremultipliedImage decodePNG(const uint8_t*, size_t); PremultipliedImage decodeJPEG(const uint8_t*, size_t); @@ -77,16 +81,26 @@ PremultipliedImage decodeImage(const std::string& string) { const uint8_t* data = reinterpret_cast(string.data()); const size_t size = string.size(); +#if !defined(__ANDROID__) && !defined(__APPLE__) + if (size >= 12) { + uint32_t riff_magic = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; + uint32_t webp_magic = (data[8] << 24) | (data[9] << 16) | (data[10] << 8) | data[11]; + if (riff_magic == 0x52494646 && webp_magic == 0x57454250) { + return decodeWebP(data, size); + } + } +#endif // !defined(__ANDROID__) && !defined(__APPLE__) + if (size >= 4) { - unsigned int magic = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; + uint32_t magic = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; if (magic == 0x89504E47U) { return decodePNG(data, size); } } if (size >= 2) { - unsigned int magic = ((data[0] << 8) | data[1]) & 0xffff; - if (magic == 0xffd8) { + uint16_t magic = ((data[0] << 8) | data[1]) & 0xffff; + if (magic == 0xFFD8) { return decodeJPEG(data, size); } } diff --git a/platform/default/webp_reader.cpp b/platform/default/webp_reader.cpp new file mode 100644 index 000000000..37d23da11 --- /dev/null +++ b/platform/default/webp_reader.cpp @@ -0,0 +1,27 @@ +#include +#include +#include + +extern "C" +{ +#include +} + +namespace mbgl { + +PremultipliedImage decodeWebP(const uint8_t* data, size_t size) { + int width = 0, height = 0; + if (WebPGetInfo(data, size, &width, &height) == 0) { + throw std::runtime_error("failed to retrieve WebP basic header information"); + } + + std::unique_ptr webp(WebPDecodeRGBA(data, size, &width, &height)); + if (!webp) { + throw std::runtime_error("failed to decode WebP data"); + } + + UnassociatedImage image { size_t(width), size_t(height), std::move(webp) }; + return util::premultiply(std::move(image)); +} + +} // namespace mbgl diff --git a/platform/linux/scripts/configure.sh b/platform/linux/scripts/configure.sh index e82437680..8510d83bd 100644 --- a/platform/linux/scripts/configure.sh +++ b/platform/linux/scripts/configure.sh @@ -15,6 +15,7 @@ VARIANT_VERSION=1.0 RAPIDJSON_VERSION=1.0.2 GTEST_VERSION=1.7.0 PIXELMATCH_VERSION=0.9.0 +WEBP_VERSION=0.5.0 function print_opengl_flags { CONFIG+=" 'opengl_cflags%': $(quote_flags $(pkg-config gl x11 --cflags)),"$LN diff --git a/src/mbgl/util/mapbox.cpp b/src/mbgl/util/mapbox.cpp index 067c9918c..d94a9a5f7 100644 --- a/src/mbgl/util/mapbox.cpp +++ b/src/mbgl/util/mapbox.cpp @@ -129,6 +129,12 @@ std::string normalizeRasterTileURL(const std::string& url) { } std::string normalizedURL(url); +#if !defined(__ANDROID__) && !defined(__APPLE__) + // Replace PNG with WebP. + if (normalizedURL.compare(extensionIdx + 1, 3, "png") == 0) { + normalizedURL.replace(extensionIdx + 1, 3, "webp"); + } +#endif // !defined(__ANDROID__) && !defined(__APPLE__) normalizedURL.insert(extensionIdx, "{ratio}"); return normalizedURL; } diff --git a/test/fixtures/image/tile.webp b/test/fixtures/image/tile.webp new file mode 100644 index 0000000000000000000000000000000000000000..5dbad8f88d21dac558a69f60cb543c626f2f64db GIT binary patch literal 8916 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 literal 0 HcmV?d00001 diff --git a/test/miscellaneous/image.cpp b/test/miscellaneous/image.cpp index 2db62b96d..9886eede4 100644 --- a/test/miscellaneous/image.cpp +++ b/test/miscellaneous/image.cpp @@ -78,6 +78,14 @@ TEST(Image, JPEGTile) { EXPECT_EQ(256, image.height); } +#if !defined(__ANDROID__) && !defined(__APPLE__) +TEST(Image, WebPTile) { + PremultipliedImage image = decodeImage(util::read_file("test/fixtures/image/tile.webp")); + EXPECT_EQ(256, image.width); + EXPECT_EQ(256, image.height); +} +#endif // !defined(__ANDROID__) && !defined(__APPLE__) + TEST(Image, Premultiply) { UnassociatedImage rgba { 1, 1 }; rgba.data[0] = 255; diff --git a/test/miscellaneous/mapbox.cpp b/test/miscellaneous/mapbox.cpp index 02a08db9e..d6f9948e6 100644 --- a/test/miscellaneous/mapbox.cpp +++ b/test/miscellaneous/mapbox.cpp @@ -37,10 +37,17 @@ TEST(Mapbox, SpriteURL) { TEST(Mapbox, TileURL) { try { +#if defined(__ANDROID__) || defined(__APPLE__) EXPECT_EQ("http://path.png/tile{ratio}.png", mbgl::util::mapbox::normalizeRasterTileURL("http://path.png/tile.png")); EXPECT_EQ("http://path.png/tile{ratio}.png32", mbgl::util::mapbox::normalizeRasterTileURL("http://path.png/tile.png32")); EXPECT_EQ("http://path.png/tile{ratio}.png70", mbgl::util::mapbox::normalizeRasterTileURL("http://path.png/tile.png70")); EXPECT_EQ("http://path.png/tile{ratio}.png?access_token=foo", mbgl::util::mapbox::normalizeRasterTileURL("http://path.png/tile.png?access_token=foo")); +#else + EXPECT_EQ("http://path.png/tile{ratio}.webp", mbgl::util::mapbox::normalizeRasterTileURL("http://path.png/tile.png")); + EXPECT_EQ("http://path.png/tile{ratio}.webp32", mbgl::util::mapbox::normalizeRasterTileURL("http://path.png/tile.png32")); + EXPECT_EQ("http://path.png/tile{ratio}.webp70", mbgl::util::mapbox::normalizeRasterTileURL("http://path.png/tile.png70")); + EXPECT_EQ("http://path.png/tile{ratio}.webp?access_token=foo", mbgl::util::mapbox::normalizeRasterTileURL("http://path.png/tile.png?access_token=foo")); +#endif // defined(__ANDROID__) || defined(__APPLE__) EXPECT_EQ("http://path.png/tile{ratio}.pbf", mbgl::util::mapbox::normalizeRasterTileURL("http://path.png/tile.pbf")); EXPECT_EQ("http://path.png/tile{ratio}.pbf?access_token=foo", mbgl::util::mapbox::normalizeRasterTileURL("http://path.png/tile.pbf?access_token=foo")); EXPECT_EQ("http://path.png/tile{ratio}.pbf?access_token=foo.png", mbgl::util::mapbox::normalizeRasterTileURL("http://path.png/tile.pbf?access_token=foo.png"));