/*
* Copyright (C) 2013 Patrick "P. J." McDermott
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program. If not, see
* .
*/
#include
#include
#include
#include "../logging.h"
#include "palette.h"
#include "resource.h"
struct resource_table pal_res;
static void palette_gpl_parse(const char *, SDL_Palette *);
struct palette *
palette_get(const char *path)
{
struct palette *pal;
pal = (struct palette *) resource_get(&pal_res, path);
if (pal != NULL) {
resource_use((struct resource *) pal);
return pal;
}
pal = resource_alloc(path, sizeof(*pal));
pal->palette = malloc(sizeof(*pal->palette));
if (pal->palette == NULL) {
err(1, "Failed to load palette \"%s\" (out of memory)", path);
}
pal->palette->colors = malloc(sizeof(*pal->palette->colors) * 240);
if (pal->palette->colors == NULL) {
err(1, "Failed to load palette \"%s\" (out of memory)", path);
}
palette_gpl_parse(path, pal->palette);
#ifdef DEBUG_PALETTES
{
int col_i;
debug("Palette \"%s\"", path);
for (col_i = 0; col_i < pal->palette->ncolors; ++col_i) {
debug(" Color %3.3d: 0x%2.2x%2.2x%2.2x",
col_i,
pal->palette->colors[col_i].r,
pal->palette->colors[col_i].g,
pal->palette->colors[col_i].b);
}
}
#endif
resource_use((struct resource *) pal);
resource_add(&pal_res, path, (struct resource *) pal);
return pal;
}
static void
palette_gpl_parse(const char *path, SDL_Palette *palette)
{
FILE *fp;
char str[1024];
int i;
char *tok;
/*
* See also:
* * gimp_palette_load()
* GIMP 2.8.2, app/core/gimppalette-load.c:53
*/
fp = fopen(path, "rb");
if (fp == NULL) {
err(1, "Failed to load palette \"%s\" (cannot open file)",
path);
}
/* GIMP Palette */
if (fgets(str, sizeof(str), fp) == NULL) {
err(1, "Failed to load palette \"%s\" (cannot read line)",
path);
}
if (strncmp(str, "GIMP Palette", 12) != 0) {
err(1, "Failed to load palette \"%s\" (bad magic header)",
path);
}
/* Name: ... */
if (fgets(str, sizeof(str), fp) == NULL) {
err(1, "Failed to load palette \"%s\" (cannot read line)",
path);
}
if (strncmp(str, "Name: ", 6) == 0) {
/* Columns: ... */
if (fgets(str, sizeof(str), fp) == NULL) {
err(1, "Failed to load palette \"%s\" "
"(cannot read line)", path);
}
if (strncmp(str, "Columns: ", 9) == 0) {
if (fgets(str, sizeof(str), fp) == NULL) {
err(1, "Failed to load palette \"%s\" "
"(cannot read line)", path);
}
}
}
i = 0;
while (!feof(fp)) {
if (str[0] != '#' && str[0] != '\n') {
if (i >= 240) {
warn("Ignoring extra colors in palette \"%s\"",
path);
break;
}
tok = strtok(str, " \t");
if (tok != NULL) {
palette->colors[i].r = atoi(tok);
} else {
warn("Bad color definition in palette \"%s\"",
path);
}
tok = strtok(NULL, " \t");
if (tok != NULL) {
palette->colors[i].g = atoi(tok);
} else {
warn("Bad color definition in palette \"%s\"",
path);
}
tok = strtok(NULL, " \t");
if (tok != NULL) {
palette->colors[i].b = atoi(tok);
} else {
warn("Bad color definition in palette \"%s\"",
path);
}
++i;
}
if (fgets(str, sizeof(str), fp) == NULL) {
if (feof(fp)) {
break;
}
err(1, "Failed to load palette \"%s\" "
"(cannot read line)", path);
}
}
palette->ncolors = i;
fclose(fp);
}
void
palette_free(struct palette *palette)
{
SDL_Palette *data;
if (palette == NULL) {
return;
}
data = palette->palette;
if (resource_free(&pal_res, (struct resource *) palette)) {
free(data->colors);
free(data);
}
}