Logo Search packages:      
Sourcecode: lebiniou version File versions  Download package

colormaps.c

/*
 *  Copyright 1994-2011 Olivier Girondel
 *
 *  This file is part of lebiniou.
 *
 *  lebiniou is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  lebiniou 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 General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with lebiniou. If not, see <http://www.gnu.org/licenses/>.
 */

#include "globals.h"
#include "colormaps.h"
#include "brandom.h"
#include "pbar.h"


Colormaps_t *colormaps = NULL;


static int
Colormaps_compare(const void *_a, const void *_b)
{
  Cmap8_t **a = (Cmap8_t **)_a;
  Cmap8_t **b = (Cmap8_t **)_b;

  assert(*a != NULL);
  assert(*b != NULL);
  assert((*a)->name != NULL);
  assert((*b)->name != NULL);

  return strcasecmp((*a)->name, (*b)->name);
}


void
Colormaps_new(const char *directoryname)
{
  DIR *dir;
  struct dirent *entry;
  GSList *tmp = NULL;
  u_short size = 0;
  GSList *t;
  PBar_t *pb = NULL;
    
  if (directoryname == NULL)
    goto error;

  dir = opendir(directoryname);
  if (dir == NULL) {
    printf("[!] Error while reading colormaps directory content: %s\n",
         strerror(errno));
    goto error;
  }

  if (libbiniou_verbose)
    pb = pbar_new();

  while ((entry = readdir(dir)) != NULL) {
    long hash;
    Cmap8_t *map;
    char *filename;
    const char *sentry = entry->d_name;

    if (sentry[0] == '.')
      continue;

    /* we only look for filenames that end with
     * ".map" (fractint colormaps)
     * or ".gpl" (GIMP colormaps)
     */
    if ((filename = strrchr(sentry, '.')) == NULL)
      /* does not have a trailing '.' -> next one */
      continue;

    if (strncmp(filename, ".map", 4*sizeof(char)) && strncmp(filename, ".gpl", 4*sizeof(char)))
      continue;

    map = Cmap8_new();
    hash = FNV_hash(sentry);
    filename = g_strdup_printf("%s/%s", directoryname, sentry);
    
    if (Cmap8_load(map, filename) != 0) {
      Cmap8_delete(map);
      g_free(filename);
      continue;
    } else {
      map->name = strdup(sentry);
      map->id = hash;
      g_free(filename);

      /* we reuse char *filename here */
      if ((filename = strrchr(map->name, '.')) != NULL)
      *filename = '\0'; /* spr0tch */

      Cmap8_findMinMax(map);
    }

    tmp = g_slist_prepend(tmp, (gpointer)map);
    size++;
            
    if (libbiniou_verbose && !(size % 5))
      pbar_step(pb);

    for (t = g_slist_next(tmp);
       t != NULL;
       t = g_slist_next(t))
      if (((Cmap8_t *)t->data)->id == hash)
      xerror("Duplicated colormap hash: %s / %s, %li\n",
             ((Cmap8_t *)t->data)->name, sentry, hash);
  }
  if (closedir(dir) == -1)
    xperror("closedir");

  colormaps = xcalloc(1, sizeof(Colormaps_t));
  if (libbiniou_verbose)
    printf("done.\n[c] Loaded %d colormaps\n", size);

  if (size) {
    u_short i;

    colormaps->cmaps = xcalloc(size, sizeof(Cmap8_t *));
    for (i = 0, t = tmp;
       t != NULL;
       t = g_slist_next(t), i++) {
      colormaps->cmaps[i] = (Cmap8_t *)t->data;
    }
    g_slist_free(tmp);
    colormaps->size = size;

    qsort((void *)colormaps->cmaps, (size_t)colormaps->size, 
        (size_t)sizeof(Cmap8_t *), &Colormaps_compare);

    if (libbiniou_verbose)
      pbar_delete(pb);

    return;
  }

 error:
  colormaps = xcalloc(1, sizeof(Colormaps_t));
  colormaps->cmaps = xcalloc(1, sizeof(Cmap8_t *));
  colormaps->size = 1;
  colormaps->cmaps[0] = Cmap8_new();
}


void
Colormaps_delete()
{
  if (colormaps != NULL) {
    u_short i;

    for (i = 0; i < colormaps->size; i++)
      Cmap8_delete(colormaps->cmaps[i]);
    xfree(colormaps->cmaps);
    xfree(colormaps);
  }
}


const char *
Colormaps_name(const long id)
{
  u_short i;
  
  assert(colormaps != NULL);
  
  for (i = 0; i < colormaps->size; i++)
    if (colormaps->cmaps[i]->id == id)
      return colormaps->cmaps[i]->name;

  if (id == 0)
    return colormaps->cmaps[0]->name;

  xerror("Colormaps_name: id %li not found\n", id);

  return NULL; /* NOTREACHED */
}


int
Colormaps_index(const long id)
{
  u_short i;
  
  assert(colormaps != NULL);
  
  for (i = 0; i < colormaps->size; i++)
    if (colormaps->cmaps[i]->id == id)
      return i;

  xerror("Colormaps_index: id %li not found\n", id);

  return -1; /* NOTREACHED */
}


long
Colormaps_find(const char *name)
{
  u_short i;

  assert(colormaps != NULL); /* should have at least a grayscale colormap */

  for (i = 0; i < colormaps->size; i++)
    if (!strcmp(colormaps->cmaps[i]->name, name))
      return colormaps->cmaps[i]->id;

  printf("[!] Colormap '%s' not found\n", name);
  return colormaps->cmaps[0]->id; /* Use the first colormap by default */
}


long
Colormaps_random_id()
{
  u_long idx = 0;

  assert(colormaps != NULL);
  
  /* printf("b_rand_int_range(0, %d)\n", cmaps->size-1); */
  if (colormaps->size > 1)
    idx = b_rand_int_range(0, colormaps->size-1);
  else {
    /* no colormaps loaded but the default */
#ifdef DEBUG
    printf("[i] Tututut no colormaps loaded, random gives the default\n");
#endif
    /* idx = 0; */ /* already initialized */
  }

  return colormaps->cmaps[idx]->id;
}

Generated by  Doxygen 1.6.0   Back to index