1// Aseprite Document Library
2// Copyright (c) 2022 Igara Studio S.A.
3// Copyright (c) 2016-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/hex.h"
14#include "base/trim_string.h"
15#include "doc/palette.h"
16
17#include <cctype>
18#include <fstream>
19#include <iomanip>
20#include <memory>
21#include <sstream>
22#include <string>
23
24namespace doc {
25namespace file {
26
27std::unique_ptr<Palette> load_hex_file(const char *filename)
28{
29 std::ifstream f(FSTREAM_PATH(filename));
30 if (f.bad())
31 return nullptr;
32
33 std::unique_ptr<Palette> pal(new Palette(frame_t(0), 0));
34
35 // Read line by line, each line one color, ignore everything that
36 // doesn't look like a hex color.
37 std::string line;
38 while (std::getline(f, line)) {
39 // Trim line
40 base::trim_string(line, line);
41
42 // Remove comments
43 if (line.empty())
44 continue;
45
46 // Find 6 consecutive hex digits
47 for (std::string::size_type i=0; i != line.size(); ++i) {
48 std::string::size_type j = i;
49 for (; j<i+6; ++j) {
50 if (!base::is_hex_digit(line[j]))
51 break;
52 }
53 if (j-i != 6)
54 continue;
55
56 // Convert text (Base 16) to integer
57 int hex = std::strtol(line.substr(i, 6).c_str(), nullptr, 16);
58 int r = (hex & 0xff0000) >> 16;
59 int g = (hex & 0xff00) >> 8;
60 int b = (hex & 0xff);
61 pal->addEntry(rgba(r, g, b, 255));
62
63 // Done, one color per line
64 break;
65 }
66 }
67
68 return pal;
69}
70
71bool save_hex_file(const Palette *pal, const char *filename)
72{
73 std::ofstream f(FSTREAM_PATH(filename));
74 if (f.bad()) return false;
75
76 f << std::hex << std::setfill('0');
77 for (int i=0; i<pal->size(); ++i) {
78 uint32_t col = pal->getEntry(i);
79 f << std::setw(2) << ((int)rgba_getr(col))
80 << std::setw(2) << ((int)rgba_getg(col))
81 << std::setw(2) << ((int)rgba_getb(col)) << "\n";
82 }
83
84 return true;
85}
86
87} // namespace file
88} // namespace doc
89