1// Aseprite Document Library
2// Copyright (c) 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/split_string.h"
14#include "base/trim_string.h"
15#include "doc/image.h"
16#include "doc/palette.h"
17
18#include <cctype>
19#include <fstream>
20#include <iomanip>
21#include <memory>
22#include <sstream>
23#include <string>
24
25namespace doc {
26namespace file {
27
28std::unique_ptr<Palette> load_pal_file(const char *filename)
29{
30 std::ifstream f(FSTREAM_PATH(filename));
31 if (f.bad())
32 return nullptr;
33
34 // Read first line, it must be "JASC-PAL"
35 std::string line;
36 if (!std::getline(f, line))
37 return nullptr;
38 base::trim_string(line, line);
39 if (line != "JASC-PAL")
40 return nullptr;
41
42 // Second line is the version (0100)
43 if (!std::getline(f, line))
44 return nullptr;
45 base::trim_string(line, line);
46 if (line != "0100")
47 return nullptr;
48
49 // Ignore number of colors (we'll read line by line anyway)
50 if (!std::getline(f, line))
51 return nullptr;
52
53 std::unique_ptr<Palette> pal(new Palette(frame_t(0), 0));
54
55 while (std::getline(f, line)) {
56 // Trim line
57 base::trim_string(line, line);
58
59 // Remove comments
60 if (line.empty())
61 continue;
62
63 int r, g, b, a=255;
64 std::istringstream lineIn(line);
65 lineIn >> r >> g >> b >> a;
66 pal->addEntry(rgba(r, g, b, a));
67 }
68
69 return pal;
70}
71
72bool save_pal_file(const Palette *pal, const char *filename)
73{
74 std::ofstream f(FSTREAM_PATH(filename));
75 if (f.bad()) return false;
76
77 f << "JASC-PAL\n"
78 << "0100\n"
79 << pal->size() << "\n";
80
81 const bool hasAlpha = pal->hasAlpha();
82 for (int i=0; i<pal->size(); ++i) {
83 uint32_t col = pal->getEntry(i);
84 f << ((int)rgba_getr(col)) << " "
85 << ((int)rgba_getg(col)) << " "
86 << ((int)rgba_getb(col));
87 if (hasAlpha) {
88 f << " " << ((int)rgba_geta(col));
89 }
90 f << "\n";
91 }
92
93 return true;
94}
95
96} // namespace file
97} // namespace doc
98