summaryrefslogtreecommitdiff
path: root/src/mbgl/sprite
diff options
context:
space:
mode:
authorJohn Firebaugh <john.firebaugh@gmail.com>2017-02-10 17:18:18 -0800
committerJohn Firebaugh <john.firebaugh@gmail.com>2017-02-14 12:29:01 -0600
commit94f011895c8e1bde36ee2ec235dbbcf2c994ac4c (patch)
tree9a9724792f87eb3c74aa2ac3d3114ca45d91471b /src/mbgl/sprite
parentc6d5eaf47941162ee6166842d5434a0e3a6c33a0 (diff)
downloadqtlocation-mapboxgl-94f011895c8e1bde36ee2ec235dbbcf2c994ac4c.tar.gz
[core] Make Image safer
Provide Image::copy, which handles copying rectangles from a source to a destination, with thorough bounds checking. Also fixes an indexing error in SpriteAtlas, where the top row of pixels in a wrapped image was copied from the wrong source row.
Diffstat (limited to 'src/mbgl/sprite')
-rw-r--r--src/mbgl/sprite/sprite_atlas.cpp56
-rw-r--r--src/mbgl/sprite/sprite_parser.cpp11
2 files changed, 19 insertions, 48 deletions
diff --git a/src/mbgl/sprite/sprite_atlas.cpp b/src/mbgl/sprite/sprite_atlas.cpp
index ea055ce5ec..61c074a942 100644
--- a/src/mbgl/sprite/sprite_atlas.cpp
+++ b/src/mbgl/sprite/sprite_atlas.cpp
@@ -231,52 +231,32 @@ optional<SpriteAtlasPosition> SpriteAtlas::getPosition(const std::string& name,
};
}
-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 SpritePatternMode mode) {
-
- int srcI = srcY * srcStride + srcX;
- int dstI = dstY * dstStride + dstX;
- int x, y;
-
- if (mode == SpritePatternMode::Repeating) {
- // 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 SpritePatternMode mode) {
if (!image.valid()) {
image = PremultipliedImage({ static_cast<uint32_t>(std::ceil(size.width * pixelRatio)),
static_cast<uint32_t>(std::ceil(size.height * pixelRatio)) });
- std::fill(image.data.get(), image.data.get() + image.bytes(), 0);
+ image.fill(0);
+ }
+
+ if (!holder.spriteImage->image.valid()) {
+ return;
}
- const uint32_t* srcData =
- reinterpret_cast<const uint32_t*>(holder.spriteImage->image.data.get());
- if (!srcData) return;
- uint32_t* const dstData = reinterpret_cast<uint32_t*>(image.data.get());
+ const uint32_t padding = 1;
+ const uint32_t x = (holder.pos.x + padding) * pixelRatio;
+ const uint32_t y = (holder.pos.y + padding) * pixelRatio;
+ const uint32_t w = holder.spriteImage->image.size.width;
+ const uint32_t h = holder.spriteImage->image.size.height;
- const int padding = 1;
+ PremultipliedImage::copy(holder.spriteImage->image, image, { 0, 0 }, { x, y }, { w, h });
- copyBitmap(srcData, holder.spriteImage->image.size.width, 0, 0, dstData, image.size.width,
- (holder.pos.x + padding) * pixelRatio, (holder.pos.y + padding) * pixelRatio,
- image.size.width * image.size.height, holder.spriteImage->image.size.width,
- holder.spriteImage->image.size.height, mode);
+ if (mode == SpritePatternMode::Repeating) {
+ // Add 1 pixel wrapped padding on each side of the image.
+ PremultipliedImage::copy(holder.spriteImage->image, image, { 0, h - 1 }, { x, y - 1 }, { w, 1 }); // T
+ PremultipliedImage::copy(holder.spriteImage->image, image, { 0, 0 }, { x, y + h }, { w, 1 }); // B
+ PremultipliedImage::copy(holder.spriteImage->image, image, { w - 1, 0 }, { x - 1, y }, { 1, h }); // L
+ PremultipliedImage::copy(holder.spriteImage->image, image, { 0, 0 }, { x + w, y }, { 1, h }); // R
+ }
dirty = true;
}
diff --git a/src/mbgl/sprite/sprite_parser.cpp b/src/mbgl/sprite/sprite_parser.cpp
index 9de8515e14..66b5ec0606 100644
--- a/src/mbgl/sprite/sprite_parser.cpp
+++ b/src/mbgl/sprite/sprite_parser.cpp
@@ -34,17 +34,8 @@ SpriteImagePtr createSpriteImage(const PremultipliedImage& image,
PremultipliedImage dstImage({ width, height });
- auto srcData = reinterpret_cast<const uint32_t*>(image.data.get());
- auto dstData = reinterpret_cast<uint32_t*>(dstImage.data.get());
-
// Copy from the source image into our individual sprite image
- for (uint32_t y = 0; y < height; ++y) {
- const auto dstRow = y * width;
- const auto srcRow = (y + srcY) * image.size.width + srcX;
- for (uint32_t x = 0; x < width; ++x) {
- dstData[dstRow + x] = srcData[srcRow + x];
- }
- }
+ PremultipliedImage::copy(image, dstImage, { srcX, srcY }, { 0, 0 }, { width, height });
return std::make_unique<const SpriteImage>(std::move(dstImage), ratio, sdf);
}