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
21namespace doc {
22namespace algorithm {
23
24void 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
55void 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