1 | // Aseprite |
2 | // Copyright (C) 2001-2015 David Capello |
3 | // |
4 | // This program is distributed under the terms of |
5 | // the End-User License Agreement for Aseprite. |
6 | |
7 | #ifndef FILTERS_NEIGHBORING_PIXELS_H_INCLUDED |
8 | #define FILTERS_NEIGHBORING_PIXELS_H_INCLUDED |
9 | #pragma once |
10 | |
11 | #include "filters/tiled_mode.h" |
12 | #include "doc/image.h" |
13 | #include "doc/image_traits.h" |
14 | |
15 | #include <vector> |
16 | |
17 | namespace filters { |
18 | using namespace doc; |
19 | |
20 | // Calls the specified "delegate" for all neighboring pixels in a 2D |
21 | // (width*height) matrix located in (x,y) where its center is the |
22 | // (centerX,centerY) element of the matrix. |
23 | template<typename Traits, typename Delegate> |
24 | inline void get_neighboring_pixels(const doc::Image* sourceImage, int x, int y, |
25 | int width, int height, |
26 | int centerX, int centerY, |
27 | TiledMode tiledMode, |
28 | Delegate& delegate) |
29 | { |
30 | // Y position to get pixel. |
31 | int getx, gety = y - centerY; |
32 | int addx, addy = 0; |
33 | if (gety < 0) { |
34 | if (int(tiledMode) & int(TiledMode::Y_AXIS)) |
35 | gety = sourceImage->height() - (-(gety+1) % sourceImage->height()) - 1; |
36 | else { |
37 | addy = -gety; |
38 | gety = 0; |
39 | } |
40 | } |
41 | else if (gety >= sourceImage->height()) { |
42 | if (int(tiledMode) & int(TiledMode::Y_AXIS)) |
43 | gety = gety % sourceImage->height(); |
44 | else |
45 | gety = sourceImage->height()-1; |
46 | } |
47 | |
48 | for (int dy=0; dy<height; ++dy) { |
49 | // X position to get pixel. |
50 | getx = x - centerX; |
51 | addx = 0; |
52 | if (getx < 0) { |
53 | if (int(tiledMode) & int(TiledMode::X_AXIS)) |
54 | getx = sourceImage->width() - (-(getx+1) % sourceImage->width()) - 1; |
55 | else { |
56 | addx = -getx; |
57 | getx = 0; |
58 | } |
59 | } |
60 | else if (getx >= sourceImage->width()) { |
61 | if (int(tiledMode) & int(TiledMode::X_AXIS)) |
62 | getx = getx % sourceImage->width(); |
63 | else |
64 | getx = sourceImage->width()-1; |
65 | } |
66 | |
67 | typename Traits::const_address_t srcAddress = |
68 | reinterpret_cast<typename Traits::const_address_t>(sourceImage->getPixelAddress(getx, gety)); |
69 | |
70 | for (int dx=0; dx<width; dx++) { |
71 | // Call the delegate for each pixel value. |
72 | delegate(*srcAddress); |
73 | |
74 | // Update X position to get pixel. |
75 | if (getx < sourceImage->width()-1) { |
76 | ++getx; |
77 | if (addx == 0) |
78 | ++srcAddress; |
79 | else |
80 | --addx; |
81 | } |
82 | else if (int(tiledMode) & int(TiledMode::X_AXIS)) { |
83 | getx = 0; |
84 | srcAddress = |
85 | reinterpret_cast<typename Traits::const_address_t>(sourceImage->getPixelAddress(getx, gety)); |
86 | } |
87 | } |
88 | |
89 | // Update Y position to get pixel |
90 | if (gety < sourceImage->height()-1) { |
91 | if (addy == 0) |
92 | ++gety; |
93 | else |
94 | --addy; |
95 | } |
96 | else if (int(tiledMode) & int(TiledMode::Y_AXIS)) |
97 | gety = 0; |
98 | } |
99 | } |
100 | |
101 | } // namespace filters |
102 | |
103 | #endif |
104 | |