1// Aseprite Document Library
2// Copyright (C) 2019-2021 Igara Studio S.A.
3// Copyright (C) 2001-2017 David Capello
4//
5// This file is released under the terms of the MIT license.
6// Read LICENSE.txt for more information.
7
8#ifndef DOC_REMAP_H_INCLUDED
9#define DOC_REMAP_H_INCLUDED
10#pragma once
11
12#include "base/debug.h"
13#include <vector>
14
15namespace doc {
16
17 class Palette;
18 class PalettePicks;
19
20 class Remap {
21 public:
22 // Unused is like a "no map" operation, we don't want to remap
23 // this entry.
24 constexpr static const int kUnused = -1;
25
26 // NoTile is to specify that we want to remap a tile to the
27 // doc::notile value.
28 constexpr static const int kNoTile = -2;
29
30 Remap(int entries = 1) : m_map(entries, 0) { }
31
32 int size() const {
33 return (int)m_map.size();
34 }
35
36 // Maps input "fromIndex" value, to "toIndex" output.
37 void map(int fromIndex, int toIndex) {
38 ASSERT(fromIndex >= 0 && fromIndex < size());
39 ASSERT(toIndex >= 0 && toIndex < size());
40 m_map[fromIndex] = toIndex;
41 }
42
43 void unused(int i) {
44 ASSERT(i >= 0 && i < size());
45 m_map[i] = kUnused;
46 }
47
48 void notile(int i) {
49 ASSERT(i >= 0 && i < size());
50 m_map[i] = kNoTile;
51 }
52
53 int operator[](int index) const {
54 //ASSERT(index >= 0 && index < size());
55 if (index >= 0 && index < size())
56 return m_map[index];
57 else
58 return index; // No remap
59 }
60
61 void merge(const Remap& other);
62 Remap invert() const;
63
64 int getMemSize() const {
65 return sizeof(*this) + sizeof(int)*size();
66 }
67
68 // Returns true if the remap can be safely used in 8-bit images.
69 bool isFor8bit() const;
70
71 // Returns true if the remap can be inverted. Remaps can be
72 // inverted when each input is mapped to one output (e.g. two
73 // inputs are not mapped to the same output). This kind of remaps
74 // are really easy to undone: You can store the inverted remap as
75 // undo data, without saving all images' pixels.
76 bool isInvertible(const PalettePicks& usedEntries) const;
77
78 // Returns true if the remap does nothing (each map entry is
79 // matched to itself).
80 bool isIdentity() const;
81
82 private:
83 std::vector<int> m_map;
84 };
85
86 // Creates a map to move a set of selected entries before the given
87 // index "beforeIndex".
88 Remap create_remap_to_move_picks(const PalettePicks& picks, int beforeIndex);
89
90 Remap create_remap_to_expand_palette(int size, int count, int beforeIndex);
91
92 Remap create_remap_to_change_palette(
93 const Palette* oldPalette, const Palette* newPalette,
94 const int oldMaskIndex,
95 const bool remapMaskIndex);
96
97} // namespace doc
98
99#endif
100