home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2002 April / pcpro0402.iso / essentials / graphics / Gimp / gimp-src-20001226.exe / src / gimp / app / patterns.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-12-20  |  8.5 KB  |  371 lines

  1. /* The GIMP -- an image manipulation program
  2.  * Copyright (C) 1995 Spencer Kimball and Peter Mattis
  3.  *
  4.  * This program is free software; you can redistribute it and/or modify
  5.  * it under the terms of the GNU General Public License as published by
  6.  * the Free Software Foundation; either version 2 of the License, or
  7.  * (at your option) any later version.
  8.  *
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17.  */
  18.  
  19. #include "config.h"
  20.  
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24.  
  25. #include <sys/types.h>
  26. #include <sys/stat.h>
  27. #ifdef HAVE_UNISTD_H
  28. #include <unistd.h>
  29. #endif
  30. #include <fcntl.h>
  31.  
  32. #ifdef G_OS_WIN32
  33. #include <io.h>
  34. #endif
  35.  
  36. #ifndef _O_BINARY
  37. #define _O_BINARY 0
  38. #endif
  39.  
  40. #ifdef HAVE_DIRENT_H
  41. #include <dirent.h>
  42. #endif
  43.  
  44. #include <glib.h>
  45.  
  46. #include "datafiles.h"
  47. #include "patterns.h"
  48. #include "pattern_header.h"
  49. #include "gimpcontext.h"
  50. #include "gimprc.h"
  51.  
  52. #include "libgimp/gimpintl.h"
  53.  
  54.  
  55. /*  global variables  */
  56. GPattern *active_pattern = NULL;
  57. GSList   *pattern_list   = NULL;
  58. gint      num_patterns   = 0;
  59.  
  60.  
  61. /*  static variables  */
  62. static GPattern *standard_pattern = NULL;
  63.  
  64.  
  65. /*  local function prototypes  */
  66. static GPattern *  pattern_load_real      (gint           fd,
  67.                        gchar         *filename,
  68.                        gboolean       quiet);
  69. static void        load_pattern           (gchar         *filename);
  70. static void        pattern_free_func      (gpointer       data, 
  71.                        gpointer       dummy);
  72. static gint        pattern_compare_func   (gconstpointer  second, 
  73.                        gconstpointer  first);
  74.  
  75. /*  public functions  */
  76.  
  77. void
  78. patterns_init (gboolean no_data)
  79. {
  80.   GSList *list;
  81.  
  82.   if (pattern_list)
  83.     patterns_free ();
  84.  
  85.   if (pattern_path != NULL && !no_data)
  86.     datafiles_read_directories (pattern_path, load_pattern, 0);
  87.  
  88.   /*  assign indexes to the loaded patterns  */
  89.   for (list = pattern_list; list; list = g_slist_next (list))
  90.     {
  91.       /*  Set the pattern index  */
  92.       ((GPattern *) list->data)->index = num_patterns++;
  93.     }
  94.  
  95.   gimp_context_refresh_patterns ();
  96. }
  97.  
  98. void
  99. patterns_free (void)
  100. {
  101.   if (pattern_list)
  102.     {
  103.       g_slist_foreach (pattern_list, pattern_free_func, NULL);
  104.       g_slist_free (pattern_list);
  105.     }
  106.  
  107.   num_patterns = 0;
  108.   pattern_list = NULL;
  109. }
  110.  
  111. GPattern *
  112. patterns_get_standard_pattern (void)
  113. {
  114.   if (! standard_pattern)
  115.     {
  116.       guchar *data;
  117.       gint row, col;
  118.  
  119.       standard_pattern = g_new (GPattern, 1);
  120.  
  121.       standard_pattern->filename = NULL;
  122.       standard_pattern->name     = g_strdup ("Standard");
  123.       standard_pattern->index    = -1;  /*  not part of the pattern list  */
  124.       standard_pattern->mask     = temp_buf_new (32, 32, 3, 0, 0, NULL);
  125.  
  126.       data = temp_buf_data (standard_pattern->mask);
  127.  
  128.       for (row = 0; row < standard_pattern->mask->height; row++)
  129.     for (col = 0; col < standard_pattern->mask->width; col++)
  130.       {
  131.         memset (data, (col % 2) && (row % 2) ? 255 : 0, 3);
  132.         data += 3;
  133.       }
  134.     }
  135.  
  136.   return standard_pattern;
  137. }
  138.  
  139. GPattern *
  140. pattern_list_get_pattern_by_index (GSList *list,
  141.                    gint    index)
  142. {
  143.   GPattern *pattern = NULL;
  144.  
  145.   list = g_slist_nth (list, index);
  146.   if (list)
  147.     pattern = (GPattern *) list->data;
  148.  
  149.   return pattern;
  150. }
  151.  
  152. GPattern *
  153. pattern_list_get_pattern (GSList *list,
  154.               gchar  *name)
  155. {
  156.   GPattern *pattern;
  157.  
  158.   for (; list; list = g_slist_next (list))
  159.     {
  160.       pattern = (GPattern *) list->data;
  161.       
  162.       if (!strcmp (pattern->name, name))
  163.     return pattern;
  164.     }
  165.  
  166.   return NULL;
  167. }
  168.  
  169. GPattern *
  170. pattern_load (gint      fd,
  171.           gchar    *filename)
  172. {
  173.   return pattern_load_real (fd, filename, TRUE);
  174. }
  175.  
  176. static GPattern *
  177. pattern_load_real (gint      fd,
  178.                gchar    *filename,
  179.                gboolean  quiet)
  180. {
  181.   GPattern      *pattern;
  182.   PatternHeader  header;
  183.   gint    bn_size;
  184.   gchar  *name;
  185.  
  186.   g_return_val_if_fail (filename != NULL, NULL);
  187.   g_return_val_if_fail (fd != -1, NULL);
  188.  
  189.   /*  Read in the header size  */
  190.   if (read (fd, &header, sizeof (header)) != sizeof (header)) 
  191.     return NULL;
  192.  
  193.   /*  rearrange the bytes in each unsigned int  */
  194.   header.header_size  = g_ntohl (header.header_size);
  195.   header.version      = g_ntohl (header.version);
  196.   header.width        = g_ntohl (header.width);
  197.   header.height       = g_ntohl (header.height);
  198.   header.bytes        = g_ntohl (header.bytes);
  199.   header.magic_number = g_ntohl (header.magic_number);
  200.  
  201.  /*  Check for correct file format */
  202.   if (header.magic_number != GPATTERN_MAGIC || header.version != 1 || 
  203.       header.header_size <= sizeof (header)) 
  204.     {
  205.       if (!quiet)
  206.     g_message (_("Unknown pattern format version #%d in \"%s\"."),
  207.            header.version, filename);
  208.       return NULL;
  209.     }
  210.   
  211.   /*  Check for supported bit depths  */
  212.   if (header.bytes != 1 && header.bytes != 3)
  213.     {
  214.       g_message ("Unsupported pattern depth: %d\n in file \"%s\"\nGIMP Patterns must be GRAY or RGB\n",
  215.          header.bytes, filename);
  216.       return NULL;
  217.     }
  218.  
  219.    /*  Read in the brush name  */
  220.   if ((bn_size = (header.header_size - sizeof (header))))
  221.     {
  222.       name = g_new (gchar, bn_size);
  223.       if ((read (fd, name, bn_size)) < bn_size)
  224.     {
  225.       g_message (_("Error in GIMP pattern file \"%s\"."), filename);
  226.       g_free (name);
  227.       return NULL;
  228.     }
  229.     }
  230.   else
  231.     {
  232.       name = g_strdup (_("Unnamed"));
  233.     }
  234.  
  235.   pattern = g_new0 (GPattern, 1);
  236.   pattern->mask = temp_buf_new (header.width, header.height, header.bytes,
  237.                 0, 0, NULL);
  238.   if (read (fd, temp_buf_data (pattern->mask), 
  239.         header.width * header.height * header.bytes) < header.width * header.height * header.bytes)
  240.       {
  241.     g_message (_("GIMP pattern file appears to be truncated: \"%s\"."),
  242.            filename);
  243.     pattern_free (pattern);
  244.     return NULL;
  245.       }
  246.  
  247.   pattern->name = name;
  248.  
  249.   return pattern;
  250. }
  251.  
  252. void
  253. pattern_free (GPattern *pattern)
  254. {
  255.   if (pattern->mask)
  256.     temp_buf_free (pattern->mask);
  257.   if (pattern->filename)
  258.     g_free (pattern->filename);
  259.   if (pattern->name)
  260.     g_free (pattern->name);
  261.  
  262.   g_free (pattern);
  263. }
  264.  
  265. /*  private functions  */
  266.  
  267. static void
  268. pattern_free_func (gpointer data,
  269.            gpointer dummy)
  270. {
  271.   pattern_free ((GPattern *) data);
  272. }
  273.  
  274. static gint
  275. pattern_compare_func (gconstpointer first,
  276.               gconstpointer second)
  277. {
  278.   return strcmp (((const GPattern *) first)->name, 
  279.          ((const GPattern *) second)->name);
  280. }
  281.  
  282. static void
  283. load_pattern (gchar *filename)
  284. {
  285.   GPattern *pattern;
  286.   gint      fd;
  287.   GSList   *list;
  288.   GSList   *list2;
  289.   gint      unique_ext = 0;
  290.   gchar    *ext;
  291.   gchar    *new_name = NULL;
  292.  
  293.   g_return_if_fail (filename != NULL);
  294.  
  295.   fd = open (filename, O_RDONLY | _O_BINARY);
  296.   if (fd == -1) 
  297.     return;
  298.  
  299.   pattern = pattern_load_real (fd, filename, FALSE);
  300.  
  301.   if (!pattern)
  302.     return;
  303.  
  304.   pattern->filename = g_strdup (filename);
  305.  
  306.   /*  Swap the pattern to disk (if we're being stingy with memory) */
  307.   if (stingy_memory_use)
  308.     temp_buf_swap (pattern->mask);
  309.  
  310.   /* uniquefy pattern name */
  311.   for (list = pattern_list; list; list = g_slist_next (list))
  312.     {
  313.       if (! strcmp (((GPattern *) list->data)->name, pattern->name))
  314.     {
  315.       ext = strrchr (pattern->name, '#');
  316.  
  317.       if (ext)
  318.         {
  319.           gchar *ext_str;
  320.  
  321.           unique_ext = atoi (ext + 1);
  322.  
  323.           ext_str = g_strdup_printf ("%d", unique_ext);
  324.  
  325.           /*  check if the extension really is of the form "#<n>"  */
  326.           if (! strcmp (ext_str, ext + 1))
  327.         {
  328.           *ext = '\0';
  329.         }
  330.           else
  331.         {
  332.           unique_ext = 0;
  333.         }
  334.  
  335.           g_free (ext_str);
  336.         }
  337.       else
  338.         {
  339.           unique_ext = 0;
  340.         }
  341.  
  342.       do
  343.         {
  344.           unique_ext++;
  345.  
  346.           g_free (new_name);
  347.  
  348.           new_name = g_strdup_printf ("%s#%d", pattern->name, unique_ext);
  349.  
  350.           for (list2 = pattern_list; list2; list2 = g_slist_next (list2))
  351.         {
  352.           if (! strcmp (((GPattern *) list2->data)->name, new_name))
  353.             {
  354.               break;
  355.             }
  356.         }
  357.         }
  358.       while (list2);
  359.  
  360.       g_free (pattern->name);
  361.  
  362.       pattern->name = new_name;
  363.  
  364.       break;
  365.     }
  366.     }
  367.  
  368.   pattern_list = g_slist_insert_sorted (pattern_list, pattern,
  369.                     pattern_compare_func);
  370. }
  371.