1 | // Aseprite Document Library
|
2 | // Copyright (c) 2001-2018 David Capello
|
3 | //
|
4 | // This file is released under the terms of the MIT license.
|
5 | // Read LICENSE.txt for more information.
|
6 |
|
7 | #ifdef HAVE_CONFIG_H
|
8 | #include "config.h"
|
9 | #endif
|
10 |
|
11 | #include "doc/algorithm/flip_image.h"
|
12 |
|
13 | #include "gfx/rect.h"
|
14 | #include "doc/image.h"
|
15 | #include "doc/mask.h"
|
16 | #include "doc/primitives.h"
|
17 |
|
18 | #include <memory>
|
19 | #include <vector>
|
20 |
|
21 | namespace doc {
|
22 | namespace algorithm {
|
23 |
|
24 | void flip_image(Image* image, const gfx::Rect& bounds, FlipType flipType)
|
25 | {
|
26 | switch (flipType) {
|
27 |
|
28 | case FlipHorizontal:
|
29 | for (int y=bounds.y; y<bounds.y+bounds.h; ++y) {
|
30 | int u = bounds.x+bounds.w-1;
|
31 | for (int x=bounds.x; x<bounds.x+bounds.w/2; ++x, --u) {
|
32 | uint32_t c1 = get_pixel(image, x, y);
|
33 | uint32_t c2 = get_pixel(image, u, y);
|
34 | put_pixel(image, x, y, c2);
|
35 | put_pixel(image, u, y, c1);
|
36 | }
|
37 | }
|
38 | break;
|
39 |
|
40 | case FlipVertical: {
|
41 | int v = bounds.y+bounds.h-1;
|
42 | for (int y=bounds.y; y<bounds.y+bounds.h/2; ++y, --v) {
|
43 | for (int x=bounds.x; x<bounds.x+bounds.w; ++x) {
|
44 | uint32_t c1 = get_pixel(image, x, y);
|
45 | uint32_t c2 = get_pixel(image, x, v);
|
46 | put_pixel(image, x, y, c2);
|
47 | put_pixel(image, x, v, c1);
|
48 | }
|
49 | }
|
50 | break;
|
51 | }
|
52 | }
|
53 | }
|
54 |
|
55 | void flip_image_with_mask(Image* image, const Mask* mask, FlipType flipType, int bgcolor)
|
56 | {
|
57 | gfx::Rect bounds = mask->bounds();
|
58 |
|
59 | switch (flipType) {
|
60 |
|
61 | case FlipHorizontal: {
|
62 | std::unique_ptr<Image> originalRow(Image::create(image->pixelFormat(), bounds.w, 1));
|
63 |
|
64 | for (int y=bounds.y; y<bounds.y+bounds.h; ++y) {
|
65 | // Copy the current row.
|
66 | originalRow->copy(image, gfx::Clip(0, 0, bounds.x, y, bounds.w, 1));
|
67 |
|
68 | int u = bounds.x+bounds.w-1;
|
69 | for (int x=bounds.x; x<bounds.x+bounds.w; ++x, --u) {
|
70 | if (mask->containsPoint(x, y)) {
|
71 | put_pixel(image, u, y, get_pixel(originalRow.get(), x-bounds.x, 0));
|
72 | if (!mask->containsPoint(u, y))
|
73 | put_pixel(image, x, y, bgcolor);
|
74 | }
|
75 | }
|
76 | }
|
77 | break;
|
78 | }
|
79 |
|
80 | case FlipVertical: {
|
81 | std::unique_ptr<Image> originalCol(Image::create(image->pixelFormat(), 1, bounds.h));
|
82 |
|
83 | for (int x=bounds.x; x<bounds.x+bounds.w; ++x) {
|
84 | // Copy the current column.
|
85 | originalCol->copy(image, gfx::Clip(0, 0, x, bounds.y, 1, bounds.h));
|
86 |
|
87 | int v = bounds.y+bounds.h-1;
|
88 | for (int y=bounds.y; y<bounds.y+bounds.h; ++y, --v) {
|
89 | if (mask->containsPoint(x, y)) {
|
90 | put_pixel(image, x, v, get_pixel(originalCol.get(), 0, y-bounds.y));
|
91 | if (!mask->containsPoint(x, v))
|
92 | put_pixel(image, x, y, bgcolor);
|
93 | }
|
94 | }
|
95 | }
|
96 | break;
|
97 | }
|
98 |
|
99 | }
|
100 | }
|
101 |
|
102 | } // namespace algorithm
|
103 | } // namespace doc
|
104 | |