gimpbrush.c 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  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. #include "config.h"
  19. #include <glib.h>
  20. #include <stdlib.h>
  21. #include <stdio.h>
  22. #include <string.h>
  23. #include <sys/types.h>
  24. #include <sys/stat.h>
  25. #ifdef HAVE_UNISTD_H
  26. #include <unistd.h>
  27. #endif
  28. #include <fcntl.h>
  29. #ifdef G_OS_WIN32
  30. #include <io.h>
  31. #endif
  32. #ifndef _O_BINARY
  33. #define _O_BINARY 0
  34. #endif
  35. #include <gtk/gtk.h>
  36. #include <stdio.h>
  37. #include "apptypes.h"
  38. #include "libgimp/gimpvector.h"
  39. #include "brush_header.h"
  40. #include "pattern_header.h"
  41. #include "gimpbrush.h"
  42. #include "gimpbrushlist.h"
  43. #include "gimpsignal.h"
  44. #include "gimprc.h"
  45. #include "paint_core.h"
  46. #include "temp_buf.h"
  47. #include "libgimp/gimpintl.h"
  48. enum
  49. {
  50. DIRTY,
  51. RENAME,
  52. LAST_SIGNAL
  53. };
  54. static GimpBrush * gimp_brush_select_brush (PaintCore *paint_core);
  55. static gboolean gimp_brush_want_null_motion (PaintCore *paint_core);
  56. static guint gimp_brush_signals[LAST_SIGNAL];
  57. static GimpObjectClass *parent_class;
  58. static void
  59. gimp_brush_destroy (GtkObject *object)
  60. {
  61. GimpBrush *brush = GIMP_BRUSH (object);
  62. g_free (brush->filename);
  63. g_free (brush->name);
  64. if (brush->mask)
  65. temp_buf_free (brush->mask);
  66. if (brush->pixmap)
  67. temp_buf_free (brush->pixmap);
  68. if (GTK_OBJECT_CLASS (parent_class)->destroy)
  69. GTK_OBJECT_CLASS (parent_class)->destroy (object);
  70. }
  71. static void
  72. gimp_brush_class_init (GimpBrushClass *klass)
  73. {
  74. GtkObjectClass *object_class;
  75. GtkType type;
  76. object_class = GTK_OBJECT_CLASS (klass);
  77. parent_class = gtk_type_class (gimp_object_get_type ());
  78. type = object_class->type;
  79. object_class->destroy = gimp_brush_destroy;
  80. klass->select_brush = gimp_brush_select_brush;
  81. klass->want_null_motion = gimp_brush_want_null_motion;
  82. gimp_brush_signals[DIRTY] =
  83. gimp_signal_new ("dirty", GTK_RUN_FIRST, type, 0, gimp_sigtype_void);
  84. gimp_brush_signals[RENAME] =
  85. gimp_signal_new ("rename", GTK_RUN_FIRST, type, 0, gimp_sigtype_void);
  86. gtk_object_class_add_signals (object_class, gimp_brush_signals, LAST_SIGNAL);
  87. }
  88. void
  89. gimp_brush_init (GimpBrush *brush)
  90. {
  91. brush->filename = NULL;
  92. brush->name = NULL;
  93. brush->spacing = 20;
  94. brush->x_axis.x = 15.0;
  95. brush->x_axis.y = 0.0;
  96. brush->y_axis.x = 0.0;
  97. brush->y_axis.y = 15.0;
  98. brush->mask = NULL;
  99. brush->pixmap = NULL;
  100. }
  101. GtkType
  102. gimp_brush_get_type (void)
  103. {
  104. static GtkType type = 0;
  105. if (!type)
  106. {
  107. static const GtkTypeInfo info =
  108. {
  109. "GimpBrush",
  110. sizeof (GimpBrush),
  111. sizeof (GimpBrushClass),
  112. (GtkClassInitFunc) gimp_brush_class_init,
  113. (GtkObjectInitFunc) gimp_brush_init,
  114. /* reserved_1 */ NULL,
  115. /* reserved_2 */ NULL,
  116. (GtkClassInitFunc) NULL
  117. };
  118. type = gtk_type_unique (gimp_object_get_type (), &info);
  119. }
  120. return type;
  121. }
  122. GimpBrush *
  123. gimp_brush_load (gchar *filename)
  124. {
  125. GimpBrush *brush;
  126. gint fd;
  127. g_return_val_if_fail (filename != NULL, NULL);
  128. fd = open (filename, O_RDONLY | _O_BINARY);
  129. if (fd == -1)
  130. return NULL;
  131. brush = gimp_brush_load_brush (fd, filename);
  132. close (fd);
  133. if (!brush)
  134. return NULL;
  135. brush->filename = g_strdup (filename);
  136. /* Swap the brush to disk (if we're being stingy with memory) */
  137. if (stingy_memory_use)
  138. {
  139. temp_buf_swap (brush->mask);
  140. if (brush->pixmap)
  141. temp_buf_swap (brush->pixmap);
  142. }
  143. return brush;
  144. }
  145. static GimpBrush *
  146. gimp_brush_select_brush (PaintCore *paint_core)
  147. {
  148. return paint_core->brush;
  149. }
  150. static gboolean
  151. gimp_brush_want_null_motion (PaintCore *paint_core)
  152. {
  153. return TRUE;
  154. }
  155. TempBuf *
  156. gimp_brush_get_mask (GimpBrush *brush)
  157. {
  158. g_return_val_if_fail (brush != NULL, NULL);
  159. g_return_val_if_fail (GIMP_IS_BRUSH (brush), NULL);
  160. return brush->mask;
  161. }
  162. TempBuf *
  163. gimp_brush_get_pixmap (GimpBrush *brush)
  164. {
  165. g_return_val_if_fail (brush != NULL, NULL);
  166. g_return_val_if_fail (GIMP_IS_BRUSH (brush), NULL);
  167. return brush->pixmap;
  168. }
  169. gchar *
  170. gimp_brush_get_name (GimpBrush *brush)
  171. {
  172. g_return_val_if_fail (brush != NULL, NULL);
  173. g_return_val_if_fail (GIMP_IS_BRUSH (brush), NULL);
  174. return brush->name;
  175. }
  176. void
  177. gimp_brush_set_name (GimpBrush *brush,
  178. gchar *name)
  179. {
  180. g_return_if_fail (brush != NULL);
  181. g_return_if_fail (GIMP_IS_BRUSH (brush));
  182. if (strcmp (brush->name, name) == 0)
  183. return;
  184. if (brush->name)
  185. g_free (brush->name);
  186. brush->name = g_strdup (name);
  187. gtk_signal_emit (GTK_OBJECT (brush), gimp_brush_signals[RENAME]);
  188. }
  189. gint
  190. gimp_brush_get_spacing (GimpBrush *brush)
  191. {
  192. g_return_val_if_fail (brush != NULL, 0);
  193. g_return_val_if_fail (GIMP_IS_BRUSH (brush), 0);
  194. return brush->spacing;
  195. }
  196. void
  197. gimp_brush_set_spacing (GimpBrush *brush,
  198. gint spacing)
  199. {
  200. g_return_if_fail (brush != NULL);
  201. g_return_if_fail (GIMP_IS_BRUSH (brush));
  202. brush->spacing = spacing;
  203. }
  204. GimpBrush *
  205. gimp_brush_load_brush (gint fd,
  206. gchar *filename)
  207. {
  208. GimpBrush *brush;
  209. GPattern *pattern;
  210. gint bn_size;
  211. BrushHeader header;
  212. gchar *name;
  213. gint i;
  214. g_return_val_if_fail (filename != NULL, NULL);
  215. g_return_val_if_fail (fd != -1, NULL);
  216. /* Read in the header size */
  217. if (read (fd, &header, sizeof (header)) != sizeof (header))
  218. return NULL;
  219. /* rearrange the bytes in each unsigned int */
  220. header.header_size = g_ntohl (header.header_size);
  221. header.version = g_ntohl (header.version);
  222. header.width = g_ntohl (header.width);
  223. header.height = g_ntohl (header.height);
  224. header.bytes = g_ntohl (header.bytes);
  225. header.magic_number = g_ntohl (header.magic_number);
  226. header.spacing = g_ntohl (header.spacing);
  227. /* Check for correct file format */
  228. /* It looks as if version 1 did not have the same magic number. (neo) */
  229. if (header.version != 1 &&
  230. (header.magic_number != GBRUSH_MAGIC || header.version != 2))
  231. {
  232. g_message (_("Unknown brush format version #%d in \"%s\"."),
  233. header.version, filename);
  234. return NULL;
  235. }
  236. if (header.version == 1)
  237. {
  238. /* If this is a version 1 brush, set the fp back 8 bytes */
  239. lseek (fd, -8, SEEK_CUR);
  240. header.header_size += 8;
  241. /* spacing is not defined in version 1 */
  242. header.spacing = 25;
  243. }
  244. /* Read in the brush name */
  245. if ((bn_size = (header.header_size - sizeof (header))))
  246. {
  247. name = g_new (gchar, bn_size);
  248. if ((read (fd, name, bn_size)) < bn_size)
  249. {
  250. g_message (_("Error in GIMP brush file \"%s\"."), filename);
  251. g_free (name);
  252. return NULL;
  253. }
  254. }
  255. else
  256. {
  257. name = g_strdup (_("Unnamed"));
  258. }
  259. switch (header.bytes)
  260. {
  261. case 1:
  262. brush = GIMP_BRUSH (gtk_type_new (gimp_brush_get_type ()));
  263. brush->mask = temp_buf_new (header.width, header.height, 1,
  264. 0, 0, NULL);
  265. if (read (fd,
  266. temp_buf_data (brush->mask), header.width * header.height) <
  267. header.width * header.height)
  268. {
  269. g_message (_("GIMP brush file appears to be truncated: \"%s\"."),
  270. filename);
  271. g_free (name);
  272. gtk_object_unref (GTK_OBJECT (brush));
  273. return NULL;
  274. }
  275. /* For backwards-compatibility, check if a pattern follows.
  276. The obsolete .gpb format did it this way. */
  277. pattern = pattern_load (fd, filename);
  278. if (pattern)
  279. {
  280. if (pattern->mask && pattern->mask->bytes == 3)
  281. {
  282. brush->pixmap = pattern->mask;
  283. pattern->mask = NULL;
  284. }
  285. pattern_free (pattern);
  286. }
  287. else
  288. {
  289. /* rewind to make brush pipe loader happy */
  290. if (lseek (fd, - ((off_t) sizeof (PatternHeader)), SEEK_CUR) < 0)
  291. {
  292. g_message (_("GIMP brush file appears to be corrupted: \"%s\"."),
  293. filename);
  294. g_free (name);
  295. gtk_object_unref (GTK_OBJECT (brush));
  296. return NULL;
  297. }
  298. }
  299. break;
  300. case 4:
  301. brush = GIMP_BRUSH (gtk_type_new (gimp_brush_get_type ()));
  302. brush->mask = temp_buf_new (header.width, header.height, 1, 0, 0, NULL);
  303. brush->pixmap = temp_buf_new (header.width, header.height, 3, 0, 0, NULL);
  304. for (i = 0; i < header.width * header.height; i++)
  305. {
  306. if (read (fd, temp_buf_data (brush->pixmap)
  307. + i * 3, 3) != 3 ||
  308. read (fd, temp_buf_data (brush->mask) + i, 1) != 1)
  309. {
  310. g_message (_("GIMP brush file appears to be truncated: \"%s\"."),
  311. filename);
  312. g_free (name);
  313. gtk_object_unref (GTK_OBJECT (brush));
  314. return NULL;
  315. }
  316. }
  317. break;
  318. default:
  319. g_message ("Unsupported brush depth: %d\n in file \"%s\"\nGIMP Brushes must be GRAY or RGBA\n",
  320. header.bytes, filename);
  321. g_free (name);
  322. return NULL;
  323. }
  324. brush->name = name;
  325. brush->spacing = header.spacing;
  326. brush->x_axis.x = header.width / 2.0;
  327. brush->x_axis.y = 0.0;
  328. brush->y_axis.x = 0.0;
  329. brush->y_axis.y = header.height / 2.0;
  330. return brush;
  331. }