Add support to load/save palettes from/to a list of hex values (.hex files)

This commit is contained in:
David Capello 2016-09-07 09:19:40 -03:00
parent 18f9d2478f
commit 5a55a9e276
6 changed files with 145 additions and 12 deletions

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2015 David Capello
// Copyright (C) 2001-2016 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -18,6 +18,7 @@
#include "doc/cel.h"
#include "doc/file/col_file.h"
#include "doc/file/gpl_file.h"
#include "doc/file/hex_file.h"
#include "doc/file/pal_file.h"
#include "doc/image.h"
#include "doc/layer.h"
@ -33,14 +34,14 @@ using namespace doc;
std::string get_readable_palette_extensions()
{
std::string buf = get_readable_extensions();
buf += ",col,gpl,pal";
buf += ",col,gpl,hex,pal";
return buf;
}
std::string get_writable_palette_extensions()
{
std::string buf = get_writable_extensions();
buf += ",col,gpl,pal";
buf += ",col,gpl,hex,pal";
return buf;
}
@ -55,6 +56,9 @@ Palette* load_palette(const char *filename)
else if (ext == "gpl") {
pal = doc::file::load_gpl_file(filename);
}
else if (ext == "hex") {
pal = doc::file::load_hex_file(filename);
}
else if (ext == "pal") {
pal = doc::file::load_pal_file(filename);
}
@ -101,6 +105,9 @@ bool save_palette(const char *filename, const Palette* pal, int columns)
else if (ext == "gpl") {
success = doc::file::save_gpl_file(pal, filename);
}
else if (ext == "hex") {
success = doc::file::save_hex_file(pal, filename);
}
else if (ext == "pal") {
success = doc::file::save_pal_file(pal, filename);
}

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2015 David Capello
// Copyright (C) 2001-2016 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -12,6 +12,7 @@
#include <string>
#include "app/ui/hex_color_entry.h"
#include "base/hex.h"
#include "gfx/border.h"
#include "ui/theme.h"
@ -19,13 +20,6 @@ namespace app {
using namespace ui;
static inline bool is_hex_digit(char digit)
{
return ((digit >= '0' && digit <= '9') ||
(digit >= 'a' && digit <= 'f') ||
(digit >= 'A' && digit <= 'F'));
}
HexColorEntry::HexColorEntry()
: Box(HORIZONTAL)
, m_label("#")
@ -56,7 +50,7 @@ void HexColorEntry::onEntryChange()
int r, g, b;
// Remove non hex digits
while (text.size() > 0 && !is_hex_digit(text[0]))
while (text.size() > 0 && !base::is_hex_digit(text[0]))
text.erase(0, 1);
// Fill with zeros at the end of the text

21
src/base/hex.h Normal file
View File

@ -0,0 +1,21 @@
// Aseprite Base Library
// Copyright (c) 2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifndef BASE_HEX_H_INCLUDED
#define BASE_HEX_H_INCLUDED
#pragma once
namespace base {
inline bool is_hex_digit(int digit) {
return ((digit >= '0' && digit <= '9') ||
(digit >= 'a' && digit <= 'f') ||
(digit >= 'A' && digit <= 'F'));
}
} // namespace base
#endif

View File

@ -32,6 +32,7 @@ add_library(doc-lib
documents.cpp
file/col_file.cpp
file/gpl_file.cpp
file/hex_file.cpp
file/pal_file.cpp
frame_tag.cpp
frame_tag_io.cpp

87
src/doc/file/hex_file.cpp Normal file
View File

@ -0,0 +1,87 @@
// Aseprite Document Library
// Copyright (c) 2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "base/fstream_path.h"
#include "base/hex.h"
#include "base/trim_string.h"
#include "base/unique_ptr.h"
#include "doc/palette.h"
#include <cctype>
#include <fstream>
#include <iomanip>
#include <sstream>
#include <string>
namespace doc {
namespace file {
Palette* load_hex_file(const char *filename)
{
std::ifstream f(FSTREAM_PATH(filename));
if (f.bad())
return nullptr;
base::UniquePtr<Palette> pal(new Palette(frame_t(0), 0));
// Read line by line, each line one color, ignore everything that
// doesn't look like a hex color.
std::string line;
while (std::getline(f, line)) {
// Trim line
base::trim_string(line, line);
// Remove comments
if (line.empty())
continue;
// Find 6 consecutive hex digits
for (int i=0; i<line.size(); ++i) {
int j = i;
for (; j<i+6; ++j) {
if (!base::is_hex_digit(line[j]))
break;
}
if (j-i != 6)
continue;
// Convert text (Base 16) to integer
int hex = std::strtol(line.substr(i, 6).c_str(), nullptr, 16);
int r = (hex & 0xff0000) >> 16;
int g = (hex & 0xff00) >> 8;
int b = (hex & 0xff);
pal->addEntry(rgba(r, g, b, 255));
// Done, one color per line
break;
}
}
return pal.release();
}
bool save_hex_file(const Palette *pal, const char *filename)
{
std::ofstream f(FSTREAM_PATH(filename));
if (f.bad()) return false;
f << std::hex << std::setfill('0');
for (int i=0; i<pal->size(); ++i) {
uint32_t col = pal->getEntry(i);
f << std::setw(2) << ((int)rgba_getr(col))
<< std::setw(2) << ((int)rgba_getg(col))
<< std::setw(2) << ((int)rgba_getb(col)) << "\n";
}
return true;
}
} // namespace file
} // namespace doc

23
src/doc/file/hex_file.h Normal file
View File

@ -0,0 +1,23 @@
// Aseprite Document Library
// Copyright (c) 2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifndef DOC_FILE_HEX_FILE_H_INCLUDED
#define DOC_FILE_HEX_FILE_H_INCLUDED
#pragma once
namespace doc {
class Palette;
namespace file {
Palette* load_hex_file(const char* filename);
bool save_hex_file(const Palette* pal, const char* filename);
} // namespace file
} // namespace doc
#endif