summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAnsis Brammanis <brammanis@gmail.com>2016-01-12 13:30:39 -0800
committerAnsis Brammanis <brammanis@gmail.com>2016-01-13 15:02:41 -0800
commite577354567c467ce5188020ba3e3a4b132a341d6 (patch)
tree96a1700b5f374b16bfa9218616cc650c454d8c87 /src
parentbdfa1277a5c28bc68a35b7fe59572d030e0a8d9e (diff)
downloadqtlocation-mapboxgl-e577354567c467ce5188020ba3e3a4b132a341d6.tar.gz
[core] remove bilinear, nearest scaling, fix #3164
Diffstat (limited to 'src')
-rw-r--r--src/mbgl/sprite/sprite_atlas.cpp78
-rw-r--r--src/mbgl/util/rect.hpp1
-rw-r--r--src/mbgl/util/scaling.cpp112
-rw-r--r--src/mbgl/util/scaling.hpp23
4 files changed, 32 insertions, 182 deletions
diff --git a/src/mbgl/sprite/sprite_atlas.cpp b/src/mbgl/sprite/sprite_atlas.cpp
index a20f6f0fe3..497721a61c 100644
--- a/src/mbgl/sprite/sprite_atlas.cpp
+++ b/src/mbgl/sprite/sprite_atlas.cpp
@@ -7,7 +7,6 @@
#include <mbgl/util/math.hpp>
#include <mbgl/util/std.hpp>
#include <mbgl/util/constants.hpp>
-#include <mbgl/util/scaling.hpp>
#include <mbgl/util/thread_context.hpp>
#include <cassert>
@@ -45,9 +44,6 @@ Rect<SpriteAtlas::dimension> SpriteAtlas::allocateImage(float src_width, float s
return rect;
}
- rect.originalW = pixel_width;
- rect.originalH = pixel_height;
-
return rect;
}
@@ -101,6 +97,34 @@ mapbox::util::optional<SpriteAtlasPosition> SpriteAtlas::getPosition(const std::
};
}
+void copyBitmap(const uint32_t *src, const uint32_t srcStride, const uint32_t srcX, const uint32_t srcY,
+ uint32_t *const dst, const uint32_t dstStride, const uint32_t dstX, const uint32_t dstY, int dstSize,
+ const int width, const int height, const bool wrap) {
+
+ int srcI = srcY * srcStride + srcX;
+ int dstI = dstY * dstStride + dstX;
+ int x, y;
+
+ if (wrap) {
+ // add 1 pixel wrapped padding on each side of the image
+ dstI -= dstStride;
+ for (y = -1; y <= height; y++, srcI = ((y + height) % height + srcY) * srcStride + srcX, dstI += dstStride) {
+ for (x = -1; x <= width; x++) {
+ const int dstIndex = (dstI + x + dstSize) % dstSize;
+ dst[dstIndex] = src[srcI + ((x + width) % width)];
+ }
+ }
+
+ } else {
+ for (y = 0; y < height; y++, srcI += srcStride, dstI += dstStride) {
+ for (x = 0; x < width; x++) {
+ const int dstIndex = (dstI + x + dstSize) % dstSize;
+ dst[dstIndex] = src[srcI + x];
+ }
+ }
+ }
+}
+
void SpriteAtlas::copy(const Holder& holder, const bool wrap) {
if (!data) {
data = std::make_unique<uint32_t[]>(pixelWidth * pixelHeight);
@@ -109,51 +133,13 @@ void SpriteAtlas::copy(const Holder& holder, const bool wrap) {
const uint32_t *srcData = reinterpret_cast<const uint32_t *>(holder.texture->data.data());
if (!srcData) return;
- const vec2<uint32_t> srcSize { holder.texture->pixelWidth, holder.texture->pixelHeight };
- const Rect<uint32_t> srcPos { 0, 0, srcSize.x, srcSize.y };
- const auto& dst = holder.pos;
-
- const int offset = 1;
-
uint32_t *const dstData = data.get();
- const vec2<uint32_t> dstSize{ pixelWidth, pixelHeight };
- const Rect<uint32_t> dstPos{ static_cast<uint32_t>((offset + dst.x) * pixelRatio),
- static_cast<uint32_t>((offset + dst.y) * pixelRatio),
- static_cast<uint32_t>(dst.originalW * pixelRatio),
- static_cast<uint32_t>(dst.originalH * pixelRatio) };
- util::bilinearScale(srcData, srcSize, srcPos, dstData, dstSize, dstPos, wrap);
+ const int padding = 1;
- // Add borders around the copied image if required.
- if (wrap) {
- // We're copying from the same image so we don't have to scale again.
- const uint32_t border = 1;
- const uint32_t borderX = dstPos.x != 0 ? border : 0;
- const uint32_t borderY = dstPos.y != 0 ? border : 0;
-
- // Left border
- util::nearestNeighborScale(
- dstData, dstSize, { dstPos.x + dstPos.w - borderX, dstPos.y, borderX, dstPos.h },
- dstData, dstSize, { dstPos.x - borderX, dstPos.y, borderX, dstPos.h });
-
- // Right border
- util::nearestNeighborScale(dstData, dstSize, { dstPos.x, dstPos.y, border, dstPos.h },
- dstData, dstSize,
- { dstPos.x + dstPos.w, dstPos.y, border, dstPos.h });
-
- // Top border
- util::nearestNeighborScale(
- dstData, dstSize, { dstPos.x - borderX, dstPos.y + dstPos.h - borderY,
- dstPos.w + border + borderX, borderY },
- dstData, dstSize,
- { dstPos.x - borderX, dstPos.y - borderY, dstPos.w + 2 * borderX, borderY });
-
- // Bottom border
- util::nearestNeighborScale(
- dstData, dstSize, { dstPos.x - borderX, dstPos.y, dstPos.w + 2 * borderX, border },
- dstData, dstSize,
- { dstPos.x - borderX, dstPos.y + dstPos.h, dstPos.w + border + borderX, border });
- }
+ copyBitmap(srcData, holder.texture->pixelWidth, 0, 0,
+ dstData, pixelWidth, (holder.pos.x + padding) * pixelRatio, (holder.pos.y + padding) * pixelRatio, pixelWidth * pixelHeight,
+ holder.texture->pixelWidth, holder.texture->pixelHeight, wrap);
dirty = true;
}
diff --git a/src/mbgl/util/rect.hpp b/src/mbgl/util/rect.hpp
index 7bb3214b9b..1dc8cb8af9 100644
--- a/src/mbgl/util/rect.hpp
+++ b/src/mbgl/util/rect.hpp
@@ -9,7 +9,6 @@ struct Rect {
inline Rect(T x_, T y_, T w_, T h_) : x(x_), y(y_), w(w_), h(h_) {}
T x = 0, y = 0;
T w = 0, h = 0;
- T originalW = 0, originalH = 0;
template <typename Number>
inline Rect operator *(Number value) const {
diff --git a/src/mbgl/util/scaling.cpp b/src/mbgl/util/scaling.cpp
deleted file mode 100644
index 9b32650511..0000000000
--- a/src/mbgl/util/scaling.cpp
+++ /dev/null
@@ -1,112 +0,0 @@
-#include "scaling.hpp"
-
-namespace {
-
-using namespace mbgl;
-
-inline uint8_t bilinearInterpolate(uint8_t tl, uint8_t tr, uint8_t bl, uint8_t br, double dx, double dy) {
- const double t = dx * (tr - tl) + tl;
- const double b = dx * (br - bl) + bl;
- return t + dy * (b - t);
-}
-
-template <size_t i>
-inline const uint8_t& b(const uint32_t& w) {
- return reinterpret_cast<const uint8_t*>(&w)[i];
-}
-
-template <size_t i>
-inline uint8_t& b(uint32_t& w) {
- return reinterpret_cast<uint8_t*>(&w)[i];
-}
-
-vec2<double> getFactor(const Rect<uint32_t>& srcPos, const Rect<uint32_t>& dstPos) {
- return {
- double(srcPos.w) / dstPos.w,
- double(srcPos.h) / dstPos.h
- };
-}
-
-vec2<uint32_t> getBounds(const vec2<uint32_t>& srcSize, const Rect<uint32_t>& srcPos,
- const vec2<uint32_t>& dstSize, const Rect<uint32_t>& dstPos,
- const vec2<double>& factor) {
- if (srcPos.x > srcSize.x || srcPos.y > srcSize.y ||
- dstPos.x > dstSize.x || dstPos.y > dstSize.y) {
- // Source or destination position is out of range.
- return { 0, 0 };
- }
-
- // Make sure we don't read/write values out of range.
- return { std::min(uint32_t(double(srcSize.x - srcPos.x) / factor.x),
- std::min(dstSize.x - dstPos.x, dstPos.w)),
- std::min(uint32_t(double(srcSize.y - srcPos.y) / factor.y),
- std::min(dstSize.y - dstPos.y, dstPos.h)) };
-}
-} // namespace
-
-namespace mbgl {
-namespace util {
-
-void bilinearScale(const uint32_t* srcData, const vec2<uint32_t>& srcSize,
- const Rect<uint32_t>& srcPos, uint32_t* dstData, const vec2<uint32_t>& dstSize,
- const Rect<uint32_t>& dstPos, bool wrap) {
- const auto factor = getFactor(srcPos, dstPos);
- const auto bounds = getBounds(srcSize, srcPos, dstSize, dstPos, factor);
-
- uint32_t x, y;
- size_t i = dstSize.x * dstPos.y + dstPos.x;
- for (y = 0; y < bounds.y; y++) {
- const double fractY = y * factor.y;
- const uint32_t Y0 = fractY;
- const uint32_t Y1 = wrap ? (Y0 + 1) % srcPos.h : (Y0 + 1);
- const uint32_t srcY0 = srcPos.y + Y0;
- const uint32_t srcY1 = std::min(srcPos.y + Y1, srcSize.y - 1);
- for (x = 0; x < bounds.x; x++) {
- const double fractX = x * factor.x;
- const uint32_t X0 = fractX;
- const uint32_t X1 = wrap ? (X0 + 1) % srcPos.w : (X0 + 1);
- const uint32_t srcX0 = srcPos.x + X0;
- const uint32_t srcX1 = std::min(srcPos.x + X1, srcSize.x - 1);
-
- const uint32_t tl = srcData[srcSize.x * srcY0 + srcX0];
- const uint32_t tr = srcData[srcSize.x * srcY0 + srcX1];
- const uint32_t bl = srcData[srcSize.x * srcY1 + srcX0];
- const uint32_t br = srcData[srcSize.x * srcY1 + srcX1];
-
- const double dx = fractX - X0;
- const double dy = fractY - Y0;
- uint32_t& dst = dstData[i + x];
- b<0>(dst) = bilinearInterpolate(b<0>(tl), b<0>(tr), b<0>(bl), b<0>(br), dx, dy);
- b<1>(dst) = bilinearInterpolate(b<1>(tl), b<1>(tr), b<1>(bl), b<1>(br), dx, dy);
- b<2>(dst) = bilinearInterpolate(b<2>(tl), b<2>(tr), b<2>(bl), b<2>(br), dx, dy);
- b<3>(dst) = bilinearInterpolate(b<3>(tl), b<3>(tr), b<3>(bl), b<3>(br), dx, dy);
- }
- i += dstSize.x;
- }
-}
-
-void nearestNeighborScale(const uint32_t* srcData, const vec2<uint32_t>& srcSize,
- const Rect<uint32_t>& srcPos, uint32_t* dstData,
- const vec2<uint32_t>& dstSize, const Rect<uint32_t>& dstPos) {
- const auto factor = getFactor(srcPos, dstPos);
- const auto bounds = getBounds(srcSize, srcPos, dstSize, dstPos, factor);
-
- double fractSrcY = srcPos.y;
- double fractSrcX;
- size_t i = dstSize.x * dstPos.y + dstPos.x;
- uint32_t srcY;
- uint32_t x, y;
- for (y = 0; y < bounds.y; y++) {
- fractSrcX = srcPos.x;
- srcY = srcSize.x * uint32_t(fractSrcY);
- for (x = 0; x < bounds.x; x++) {
- dstData[i + x] = srcData[srcY + uint32_t(fractSrcX)];
- fractSrcX += factor.x;
- }
- i += dstSize.x;
- fractSrcY += factor.y;
- }
-}
-
-} // namespace util
-} // namespace mbgl
diff --git a/src/mbgl/util/scaling.hpp b/src/mbgl/util/scaling.hpp
deleted file mode 100644
index a2d582de1c..0000000000
--- a/src/mbgl/util/scaling.hpp
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef MBGL_UTIL_SCALING
-#define MBGL_UTIL_SCALING
-
-
-#include <mbgl/util/vec.hpp>
-#include <mbgl/util/rect.hpp>
-
-#include <cstdint>
-
-namespace mbgl {
-namespace util {
-
-void bilinearScale(const uint32_t* srcData, const vec2<uint32_t>& srcSize,
- const Rect<uint32_t>& srcPos, uint32_t* dstData, const vec2<uint32_t>& dstSize,
- const Rect<uint32_t>& dstPos, bool wrap);
-
-void nearestNeighborScale(const uint32_t* srcData, const vec2<uint32_t>& srcSize,
- const Rect<uint32_t>& srcPos, uint32_t* dstData,
- const vec2<uint32_t>& dstSize, const Rect<uint32_t>& dstPos);
-} // namespace util
-} // namespace mbgl
-
-#endif