1 | // Aseprite Document Library |
2 | // Copyright (c) 2020-2022 Igara Studio S.A. |
3 | // Copyright (c) 2001-2018 David Capello |
4 | // |
5 | // This file is released under the terms of the MIT license. |
6 | // Read LICENSE.txt for more information. |
7 | |
8 | #ifdef HAVE_CONFIG_H |
9 | #include "config.h" |
10 | #endif |
11 | |
12 | #include "base/fstream_path.h" |
13 | #include "base/serialization.h" |
14 | #include "doc/palette.h" |
15 | |
16 | #include <algorithm> |
17 | #include <cctype> |
18 | #include <fstream> |
19 | #include <memory> |
20 | |
21 | namespace doc { |
22 | namespace file { |
23 | |
24 | using namespace base::serialization::big_endian; |
25 | |
26 | const int ActMaxColors = 256; |
27 | |
28 | std::unique_ptr<Palette> load_act_file(const char *filename) |
29 | { |
30 | std::ifstream f(FSTREAM_PATH(filename), std::ios::binary); |
31 | if (f.bad()) |
32 | return nullptr; |
33 | |
34 | // Each color is a 24-bit RGB value |
35 | uint8_t rgb[ActMaxColors * 3] = { 0 }; |
36 | f.read(reinterpret_cast<char*>(&rgb), sizeof(rgb)); |
37 | |
38 | int colors = ActMaxColors; |
39 | // If there's extra bytes, it's the number of colors to use |
40 | if (!f.eof()) { |
41 | colors = std::min(read16(f), (uint16_t)ActMaxColors); |
42 | } |
43 | |
44 | std::unique_ptr<Palette> pal(new Palette(frame_t(0), colors)); |
45 | |
46 | uint8_t *c = rgb; |
47 | for (int i = 0; i < colors; ++i) { |
48 | uint8_t r = *(c++); |
49 | uint8_t g = *(c++); |
50 | uint8_t b = *(c++); |
51 | |
52 | pal->setEntry(i, rgba(r, g, b, 255)); |
53 | } |
54 | |
55 | return pal; |
56 | } |
57 | |
58 | bool save_act_file(const Palette *pal, const char *filename) |
59 | { |
60 | std::ofstream f(FSTREAM_PATH(filename), std::ios::binary); |
61 | if (f.bad()) |
62 | return false; |
63 | |
64 | // Need to write 256 colors even if the palette is smaller |
65 | uint8_t rgb[ActMaxColors * 3] = { 0 }; |
66 | uint8_t *c = rgb; |
67 | |
68 | int colors = std::min(pal->size(), ActMaxColors); |
69 | for (int i = 0; i < colors; ++i) { |
70 | uint32_t col = pal->getEntry(i); |
71 | |
72 | *(c++) = rgba_getr(col); |
73 | *(c++) = rgba_getg(col); |
74 | *(c++) = rgba_getb(col); |
75 | } |
76 | f.write(reinterpret_cast<char*>(&rgb), sizeof(rgb)); |
77 | |
78 | write16(f, colors); |
79 | write16(f, 0); |
80 | |
81 | return true; |
82 | } |
83 | |
84 | } // namespace file |
85 | } // namespace doc |
86 | |